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
}