访问Android NotificationListenerService设置



Android自4.3起提供了新的通知侦听器服务:http://developer.android.com/about/versions/jelly-bean.htmlhttp://developer.android.com/reference/android/service/notification/NotificationListenerService.html

来自文档:

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

我看不出任何地方有开火的意图。浏览"设置"文档似乎没有帮助:http://developer.android.com/reference/android/provider/Settings.html

直接查看Settings类: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_SETTING:

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:找不到要执行的活动handle Intent{act=android.settings.NOTIFICATION_LISTENER_settings})

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

我是不是错过了什么?

在上一个例子中,您将一个操作字符串与一个类名混为一谈。"手动"方法是:

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

至于为什么安卓工作室没有找到Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS,我不能说。


更新

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

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

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

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

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

请注意,不幸的是,这在其他各种情况下都是不可能的。甚至没有突出显示&集中对于这些情况,我提出了以下请求:

  • https://issuetracker.google.com/issues/163176781
  • https://issuetracker.google.com/issues/165311852
  • https://issuetracker.google.com/issues/160303945

感谢@android开发者的精彩回答,但我有一点澄清。

您必须在try/catch中调用startActivity,因为某些操作系统(Honor/Whuawei on Android 11)没有";设置.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()
        }
    }
}

我测试了@android开发者代码,但它在我的设备上不起作用(三星s22 ultra android 13),所以我修改了他的代码,现在它正在打开NotificationListenerService设置并突出显示筛选我的应用

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

相关内容

  • 没有找到相关文章

最新更新