有什么方法可以链接到我的应用的Android通知设置?


81

有什么方法可以启动我的应用程序以进入Android的通知设置屏幕(如下图所示)?还是一种简单的方法,使我可以创建一个PreferenceScreen项,从而使它在单击时就引向此处?

在此处输入图片说明


看起来是Settings.ACTION_APPLICATION_DETAILS_SETTINGS将带我进入主应用程序信息屏幕,但我正在尝试进一步迈入应用程序信息屏幕上的“通知”设置...
Mohamed Hafez 2015年

当我们使用@ mohamed-hafez时,您能否在此处解释如何锚定此“应用程序设置”条目?我认为这是通过清单中的意图过滤器完成的,但是没有做到。谢谢!
加百利

@Gabriel,看来您已经找到了问题的答案,但是对于其他感兴趣的人,答案就在这里
山姆

如何打开应用程序通知类别(默认)?在orio。我们可以在其中更改声音,振动和其他设置的地方
Sagar

Answers:


144

以下将在Android 5.0(Lollipop)及更高版本中工作:

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);

注意:Android 5-7并未正式支持此功能,但效果很好。从Android 8开始正式支持该代码。此代码与5.0之前的Android版本不向后兼容。


@shhp-谢谢您的回答。也可以在N预览中使用。您能用几句话说出您是如何找到该解决方案的吗?我在调查中得到的最远的是以下日志消息:com.android.settings D/SubSettings: Launching fragment com.android.settings.notification.AppNotificationSettings单击应用程序设置中的“通知”行。link2src
Dev-iL

@ Dev-iL您迈出了第一步。然后,我检查了源代码,以了解应在intent:-)中添加哪些额外内容
shhp

1
这很酷,但是用户应注意以下几点:1)此意图依赖于Settings应用程序的内部/隐藏代码,因此无法保证将来Settings应用程序不会更改并且不再使用相同的String操作,组件或Intent Extras打开应用程序特定的通知屏幕。2)此方法不完全向后兼容。大约2年前介绍了String动作和使用的组件。看到提交在这里
Tony Chan

@TonyChan谢谢您的提醒。我将在答案中添加它们。
shhp

刚刚进行了编辑,因此除了Android 5-7外,它还可以与Android O一起使用。注意:Android O正式支持此功能!
Mohamed Hafez

77

我合并了Sergei和Shhp的解决方案以支持所有情况:

    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);

12

我已为Android 8.0 Oreo API 26或更高版本添加了频道通知设置。Android 4.4 KitKat提供了一个解决方案。

频道通知设置的用法:

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

应用通知设置的用法:

goToNotificationSettings(null, mContext);

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);
}

1
Settings.ACTION_APP_NOTIFICATION_SETTINGS可从API> = Build.VERSION_CODES.O因此它不应该在N_MR1使用developer.android.com/reference/android/provider/...
安特

里面的代码if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)将永远不会执行,在某些部分中您正确使用了某些部分,Settings.ACTION_APP_NOTIFICATION_SETTINGS但在其他部分中则使用了硬编码字符串"android.settings.APP_NOTIFICATION_SETTINGS"
Hugo Allexis Cardona

5

我使用以下代码(kitkat和下一版本):

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);
}

3

我合并了上面一些答案的代码,并进行了少许编辑,我已经测试过,并且在Android KitKat,Lollipop,棉花糖,牛轧糖,Oreo和Pie,API级别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           

    }

}

3

对于懒惰的人,这是@Helix的kotlin版本:

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)
}

2

我想提供@Helix答案的干净代码版本:

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)
}

当分支成一个紧凑的类时,甚至可以走得更远。并创建一个工厂when


1

使用ACTION_APP_NOTIFICATION_SETTINGS将列出该应用程序的所有频道:

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

要打开单个通道的设置,可以使用ACTION_CHANNEL_NOTIFICATION_SETTINGS

您可以在其中更改sound,vibration.etc单个频道的设置。

 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);
   } 

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);
    }

SCHEME常数是多少?
Atetc

看起来分支else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1)将永远不会被称为
Atetc

0

最后,我测试了几乎所有设备并正常工作。给出的代码如下

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
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.