检查用户是否已授予我的应用程序通知监听器访问权限。

13

我正在使用这段代码打开通知监听器设置:

startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
我想检查用户是否已授权我的应用程序。 我已经尝试检查我的NotificationListenerService是否正在运行,但似乎它被系统停止并重新启动(即使我返回START_STICKY)。

我希望您能够检查用户是否已经授权我的应用程序。我已尝试检查我的NotificationListenerService是否在运行,但似乎系统会将其暂停并重新启动(即使我返回START_STICKY)。


我使用了这个解决方案,它很好用:http://stackoverflow.com/a/33871952/5053585 - Nammen8
6个回答

33

唯一正确的做法是检查安全设置:

ComponentName cn = new ComponentName(context, YourNotificationListenerService.class);
String flat = Settings.Secure.getString(context.getContentResolver(), "enabled_notification_listeners");
final boolean enabled = flat != null && flat.contains(cn.flattenToString());

2
我真的想给你一个饼干!谢谢。 - Olayinka
1
这个可以工作。您也可以通过将“enabled_accessibility_services”传递给“Settings.Secure.getString()”来检查您的AccessibilityService。这两个字符串都设置为Settings.Secure中的常量,但通知的那个由于某种原因被隐藏了。 - Steve Blackwell
无法工作。尽管已经批准,但此代码返回false。 - Udi Oshi

7

我错了,检查服务是否运行是有效的:

    private boolean isNLServiceRunning() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
             if (NLService.class.getName().equals(service.service.getClassName())) {
                  return true;
             }
        }

        return false;
    }

4
如果取消勾选权限,该进程仍将继续运行。因此,这并非百分之百可靠的方法,但我没有找到其他方式。 - black
2
如果我取消勾选权限,我的服务将被销毁。因此上面的答案对我来说完美适用。 - MrMaffen

5
如果您正在使用AndroidX,可以使用以下代码:
NotificationManagerCompat.getEnabledListenerPackages(Context context)

检查你的监听器是否已启用。 来源


0
internal fun isNotificationServiceEnable(context: Context): Boolean {
    val myNotificationListenerComponentName = ComponentName(context, NotificationListener::class.java)
    val enabledListeners =
        Settings.Secure.getString(context.contentResolver, "enabled_notification_listeners")

    if (enabledListeners.isEmpty()) return false

    return enabledListeners.split(":").map {
        ComponentName.unflattenFromString(it)
    }.any {componentName->
        myNotificationListenerComponentName == componentName
    }
}

0

在浏览 Android Studio 文档时看到了这个内容

只读列表,列出当前用户明确允许查看所有用户通知的服务组件,以 ':' 分隔。

@hide
 @deprecated Use
 {@link NotificationManager#isNotificationListenerAccessGranted(ComponentName)}.
    @Deprecated
@UnsupportedAppUsage
@Readable
public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";

因此,我将其制作并添加到一个公开可访问的类中。
 private fun notificationAccess(context: Context): Boolean {
        val mNotificationManager =
            context.getSystemService(NotificationListenerService.NOTIFICATION_SERVICE) as NotificationManager?;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            Log.d(TAG, "notificationAccess: >27 ")
            val status=mNotificationManager?.isNotificationListenerAccessGranted(
                ComponentName(
                    context,
                    NotificationService::class.java
                )
            )
            return status == true
        } else {
            Log.d(TAG, "notificationAccess: LESS THAN 27")
            try {

                val contentResolver = context.contentResolver
                val listeners =
                    Settings.Secure.getString(contentResolver, "enabled_notification_listeners")
                return !(listeners == null || !listeners.contains(BuildConfig.APPLICATION_ID))
            } catch (e: Exception) {
                if (DEBUG) e.printStackTrace()
            }
        }
        return false
    }

我已经测试了27以上的API,请在进入生产之前先测试27以下的API。


0
这个被接受的答案给了我灵感,让我想出了这个答案:
class NotificationListener : NotificationListenerService() {
    internal companion object {
        private var notRunning = true

        internal fun notRunning(): Boolean {
            return notRunning
        }
    }

    override fun onListenerDisconnected() {
        super.onListenerDisconnected()
        notRunning = true
    }

    override fun onListenerConnected() {
        super.onListenerConnected()
        notRunning = false
    }
}

基本上,这个功能在通知服务中创建了一个静态函数,使用onListenerConnectedonListenerDisconnected来报告服务当前是否正在运行。当权限被关闭时,onListenerDisconnected会触发。
然后,你只需要检查NotificationListener.notRunning()来判断它是否在运行。近期的Android版本中,ActivityManager的功能受到了很大的限制,但这个功能使用了标准的常见方法来工作。
你可以使用onListenerDisconnected来触发你的应用程序中的代码,以优雅地处理通知访问的丢失,或者提示用户。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接