93

Is there any way I can launch an intent to get to Android's notification settings screen for my app (pictured below)? Or an easy way I can make a PreferenceScreen item that just leads here on a click?

enter image description here

Mohamed Hafez
  • 8,151
  • 6
  • 38
  • 49
  • 1
    It looks like Settings.ACTION_APPLICATION_DETAILS_SETTINGS will get me to the main app info screen, but I'm trying to get one step further into the Notification settings on the app info screen... – Mohamed Hafez Sep 03 '15 at 04:40
  • 1
    While we're at it @mohamed-hafez, could you explain how you did to anchor this "App settings" entry here? I head that it's done via an intent-filter in the Manifest, but failed to do it. Thanks! – Gabriel May 04 '16 at 13:01
  • 1
    @Gabriel, looks like you already found the answer to your question, but for anyone else interested, the answer is [here](http://stackoverflow.com/a/28710214/238753). – Sam Dec 12 '16 at 09:58
  • how to open app notification category (Default) ? on orio. where we can change sound,vibration and other setting – Sagar Oct 17 '18 at 07:54

10 Answers10

156

The following will work in Android 5.0 (Lollipop) and above:

Intent intent = new Intent();
intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");

//for Android 5-7
intent.putExtra("app_package", getPackageName());
intent.putExtra("app_uid", getApplicationInfo().uid);

// for Android 8 and above
intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());

startActivity(intent);

Notes: This is not officially supported in Android 5-7, but it works just fine. It IS officially supported as of Android 8. This code is not backwards compatible with versions of Android before 5.0.

Mohamed Hafez
  • 8,151
  • 6
  • 38
  • 49
shhp
  • 3,313
  • 2
  • 16
  • 23
  • @shhp - Thank you for this answer. Also works in N preview. Would you please say in a few words how you found this solution? The farthest I got in this investigation was this log message: `com.android.settings D/SubSettings: Launching fragment com.android.settings.notification.AppNotificationSettings` when clicking the "Notifications" line in app settings. [link2src](https://android.googlesource.com/platform/packages/apps/Settings/+/master/src/com/android/settings/notification/AppNotificationSettings.java) – Dev-iL Mar 12 '16 at 08:27
  • @Dev-iL you get the first step. Then I checked the source code to see what extras should be put in the `intent` :-) – shhp Mar 13 '16 at 06:28
  • 1
    This is cool, but users should be aware of a few things: 1) This intent relies on internal/hidden code of the `Settings` app, so there's no guarantee that in the future the `Settings` app won't change and no longer use the same String action, component, or Intent extras to open the app specific notification screen. 2) This method is not completely backward compatible. The String action and components used were introduced about 2 years ago. [**See commit here**](https://android.googlesource.com/platform/packages/apps/Settings/+/802ddf99f57e316d0fd87c2cfeed5dc3a0cfa8fe) – Tony Chan Oct 12 '16 at 00:34
  • @TonyChan Thank you for the reminder. I will add them in the answer. – shhp Oct 12 '16 at 01:47
  • Just edited so this will work with Android O, in addition to Android 5-7. Note: this is officially supported in Android O! – Mohamed Hafez Jun 01 '17 at 19:03
  • 1
    Just a side note: you can also reach the specific notification channel setting, as shown here: https://stackoverflow.com/a/48854197/878126 – android developer Apr 08 '18 at 22:51
  • @shhp how to open apps notification categories on Android Oreo – Sagar Oct 17 '18 at 07:16
  • @SagarHudge sorry, have no idea for the moment. – shhp Oct 18 '18 at 02:14
85

I merged the solution of Sergei and Shhp to support all the cases :

    Intent intent = new Intent();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
        intent.putExtra("app_package", context.getPackageName());
        intent.putExtra("app_uid", context.getApplicationInfo().uid);
    } else {
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(Uri.parse("package:" + context.getPackageName()));
    }
    context.startActivity(intent);
ElegyD
  • 3,391
  • 1
  • 17
  • 35
Helix
  • 1,024
  • 8
  • 14
14

I've appended Channel Notification Settings for Android 8.0 Oreo API 26 or later. There is a solution from Android 4.4, KitKat.

Usage for Channel notification settings:

// PRIMARY_CHANNEL:
goToNotificationSettings(getString(R.string.PRIMARY_CHANNEL), mContext);
// SECONDARY_CHANNEL:
goToNotificationSettings(getString(R.string.SECONDARY_CHANNEL), mContext);

Usage for App notification settings:

goToNotificationSettings(null, mContext);

The method of goToNotificationSettings:

public void goToNotificationSettings(String channel, Context context) {
    Intent intent = new Intent();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
        if (channel != null) {
            intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel);
        } else {
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        }
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        if (channel != null) {
            intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel);
        } else {
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        }
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
    } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
    } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
        intent.putExtra("app_package", context.getPackageName());
        intent.putExtra("app_uid", context.getApplicationInfo().uid);
    } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(Uri.parse("package:" + context.getPackageName()));
    }
    context.startActivity(intent);
}
Andy Sander
  • 1,838
  • 1
  • 11
  • 16
  • 1
    Settings.ACTION_APP_NOTIFICATION_SETTINGS is available from API >= Build.VERSION_CODES.O so it shouldn't be used on N_MR1 https://developer.android.com/reference/android/provider/Settings.html#ACTION_APP_NOTIFICATION_SETTINGS – Ante Jan 08 '18 at 15:00
  • code inside `if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)` will never be executed, in some parts you're correctly using `Settings.ACTION_APP_NOTIFICATION_SETTINGS` but in some others you're using hardcode string `"android.settings.APP_NOTIFICATION_SETTINGS"` – Hugo Allexis Cardona Jun 07 '18 at 19:40
8

For lazy men this is the kotlin version of @Helix answer:

fun openAppNotificationSettings(context: Context) {
    val intent = Intent().apply {
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
                action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
                putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
            }
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
                action = "android.settings.APP_NOTIFICATION_SETTINGS"
                putExtra("app_package", context.packageName)
                putExtra("app_uid", context.applicationInfo.uid)
            }
            else -> {
                action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                addCategory(Intent.CATEGORY_DEFAULT)
                data = Uri.parse("package:" + context.packageName)
            }
        }
    }
    context.startActivity(intent)
}
carlol
  • 2,040
  • 1
  • 14
  • 10
5

I use this code (kitkat and next versions):

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    Intent intent = new Intent();
    intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
    intent.putExtra("app_package", getActivity().getPackageName());
    intent.putExtra("app_uid", getActivity().getApplicationInfo().uid);
    startActivity(intent);
} else if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
    Intent intent = new Intent();
    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    intent.setData(Uri.parse("package:" + getActivity().getPackageName()));
    startActivity(intent);
}
Sergei K
  • 727
  • 10
  • 11
3

I merged the code of some of the answers above and added little edit, I have tested and it working fine on Android KitKat, Lollipop, Marshmallow, Nougat, Oreo and Pie, API level 19 - 28

public void goToNotificationSettings(Context context) {

    String packageName = context.getPackageName();

    try {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {

            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
            intent.addFlags(FLAG_ACTIVITY_NEW_TASK);

        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {

            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra("android.provider.extra.APP_PACKAGE", packageName);

        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", packageName);
            intent.putExtra("app_uid", context.getApplicationInfo().uid);

        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {

            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse("package:" + packageName));

        } else {
            return;
        }

        startActivity(intent);

    } catch (Exception e) {
        // log goes here           

    }

}
NewDevin
  • 31
  • 3
1

Using ACTION_APP_NOTIFICATION_SETTINGS will list all channels of the app:

Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
    .putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
startActivity(intent);

To open the settings for a single channel, you can use ACTION_CHANNEL_NOTIFICATION_SETTINGS:

Where you can change sound,vibration.etc settings for individual channel.

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
 Intent intent = new Intent("android.settings.CHANNEL_NOTIFICATION_SETTINGS");
        intent.putExtra("android.provider.extra.CHANNEL_ID", "ChannelID");
        intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
        startActivity(intent);
   } 
Sagar
  • 3,781
  • 3
  • 26
  • 40
1

I'd like to present a clean-code version of @Helix answer:

fun openNotificationsSettings() {
    val intent = Intent()
    when {
        Build.VERSION.SDK_INT > Build.VERSION_CODES.O -> intent.setOpenSettingsForApiLarger25()
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> intent.setOpenSettingsForApiBetween21And25()
        else -> intent.setOpenSettingsForApiLess21()
    }
    app.startActivity(intent)
}

private fun Intent.setOpenSettingsForApiLarger25(){
    action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
    putExtra("android.provider.extra.APP_PACKAGE", app.packageName)
}

private fun Intent.setOpenSettingsForApiBetween21And25(){
    action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
    putExtra("app_package", app.packageName)
    putExtra("app_uid", app.applicationInfo?.uid)
}

private fun Intent.setOpenSettingsForApiLess21(){
    action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
    addCategory(Intent.CATEGORY_DEFAULT)
    data = Uri.parse("package:" + app.packageName)
}

One can go even further and extract each when branch into a compact class. And create a factory in which when would be.

Kirill Starostin
  • 609
  • 5
  • 15
0
public static void goToNotificationSettings(Context context) {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.fromParts(SCHEME, context.getPackageName(), null));
        } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", context.getPackageName());
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", context.getPackageName());
            intent.putExtra("app_uid", context.getApplicationInfo().uid);
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
        } else {
            return;
        }
        context.startActivity(intent);
    }
Jose Gómez
  • 2,891
  • 2
  • 28
  • 52
itzhar
  • 11,479
  • 6
  • 50
  • 57
0

Finally i tested almost all devices and works fine. The code given as follows

public void goToPushSettingPage(Context context) {
    try {
        Intent intent=new Intent();
        if(Build.VERSION.SDK_INT>Build.VERSION_CODES.N_MR1){
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_APP_PACKAGE,context.getPackageName());
        }else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
            intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(ConstUtil.PUSH_SETTING_APP_PACKAGE,context.getPackageName());
            intent.putExtra(ConstUtil.PUSH_SETTING_APP_UID,context.getApplicationInfo().uid);
        }else{
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse(ConstUtil.PUSH_SETTING_URI_PACKAGE+context.getPackageName()));
        }
        startActivity(intent);
    } catch (Exception e) {
        // log goes here
    }
}
Farid Haq
  • 1,919
  • 15
  • 13