12

从 4.3 开始,Android 有一个新的通知侦听器服务:http: //developer.android.com/about/versions/jelly-bean.html http://developer.android.com/reference/android/service/notification/NotificationListenerService。 html

从文档:

默认情况下禁用通知访问——应用程序可以使用新的 Intent 将用户直接带到设置以在安装后启用侦听器服务。

我没有看到任何地方记录的开火意图。仔细阅读设置文档似乎没有帮助:http: //developer.android.com/reference/android/provider/Settings.html

直接看设置类: https ://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/provider/Settings.java

我看到定义了 ACTION_NOTIFICATION_LISTENER_SETTINGS,但是当使用 Android Studio 并指向 4.3 ACTION_NOTIFICATION_LISTENER_SETTINGS 时无法解决:

Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);

手动尝试似乎不起作用:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClassName("com.android.settings", "android.settings.NOTIFICATION_LISTENER_SETTINGS");

编辑:按照CommonsWare在下面指出的正确方式进行操作:

Intent intent=new Intent("android.settings.NOTIFICATION_LISTENER_SETTINGS");

导致崩溃:

(android.content.ActivityNotFoundException:未找到处理 Intent { act=android.settings.NOTIFICATION_LISTENER_SETTINGS } 的活动)

我错过了什么吗?我不确定如何将用户发送到正确的设置屏幕以在我的应用程序中启用此服务。

4

4 回答 4

17

我错过了什么吗?

好吧,在最后一个中,您将操作字符串与类名混为一谈。“手动”方法是:

Intent intent=new Intent("android.settings.NOTIFICATION_LISTENER_SETTINGS");

至于为什么 Android Studio 没有找到Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS,我不能说。


更新

根据评论中的讨论,Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS目前不在 Android SDK 中(标有@hide)。此外,设置应用程序的清单具有稍微不同的操作字符串版本:

Intent intent=new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
于 2013-07-25T15:19:35.627 回答
7

CommonsWare 答案的补充是如何检查您是否拥有该权限

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {        
    if (!NotificationManagerCompat.getEnabledListenerPackages(this).contains(getPackageName())) {        //ask for permission
       Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
       startActivity(intent);
    }
}
于 2016-11-03T08:52:20.167 回答
4

这就是您今天可以使用它的方式,因为它将尝试为用户执行尽可能少的步骤来打开它:

@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
fun getIntentForNotificationAccess(packageName: String, notificationAccessServiceClass: Class<out NotificationListenerService>): Intent =
        getIntentForNotificationAccess(packageName, notificationAccessServiceClass.name)


@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
fun getIntentForNotificationAccess(packageName: String, notificationAccessServiceClassName: String): Intent {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        return Intent(Settings.ACTION_NOTIFICATION_LISTENER_DETAIL_SETTINGS)
                .putExtra(Settings.EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME, ComponentName(packageName, notificationAccessServiceClassName).flattenToString())
    }
    val intent = Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
    val value = "$packageName/$notificationAccessServiceClassName"
    val key = ":settings:fragment_args_key"
    intent.putExtra(key, value)
    intent.putExtra(":settings:show_fragment_args", Bundle().also { it.putString(key, value) })
    return intent
}

示例用法:

startActivityForResult(getIntentForNotificationAccess(packageName, NotiService::class.java), REQUEST_CODE)

或者:

startActivityForResult(getIntentForNotificationAccess(packageName, NotiService::class.java.name), REQUEST_CODE)

请注意,遗憾的是,对于其他各种情况,这是不可能的。甚至没有突出和聚焦。对于这些情况,我提出了以下要求:

于 2020-09-16T06:39:31.483 回答
0

感谢@android 开发人员的出色回答,但我有一点澄清。

您必须在 try/catch 中调用 startActivity,因为某些操作系统(Android 11 上的荣誉/华为)没有“Settings.ACTION_NOTIFICATION_LISTENER_DETAIL_SETTINGS”,因此会引发此异常:

No Activity found to handle Intent { act=android.settings.NOTIFICATION_LISTENER_DETAIL_SETTINGS (has extras) }

以这种方式使用:

try {
    startActivity(getIntentForNotificationAccess(packageName, NotiService::class.java))
} catch (e: Exception) {
    if (Build.VERSION.SDK_INT >= 22) {
        try {
            startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS))
        } catch (e1: Exception) {
            e1.printStackTrace()
        }
    }
}
于 2022-02-19T10:42:16.533 回答