使用NotificationListenerService检查对通知的访问

Nic*_*ick 24 notifications android

我正在使用> = 4.3 NotificationListenerService来访问通知.在第一次启动时,我的应用程序将用户带到"访问通知"系统面板,但是只要禁用"访问通知"中我的应用程序的复选框,我就会将用户带到那里.我没有在isNotificationAccessEnabled()任何地方找到一个方法,但我肯定知道这是可能的,因为像Krome这样的应用程序也是这样做的.

Cha*_*ere 56

编辑2016年6月15日

我不确定添加了哪个版本的支持库,但看起来现在内置了这个功能.只需使用:

NotificationManagerCompat.getEnabledListenerPackages(context);(链接到docs)

这将返回一个Set<String>您可以迭代查找包名称的内容.但请注意,我没有亲自测试过这个.但看起来可能更倾向于使用它代替我下面的旧解决方案.


旧解决方案

此代码适用于我的应用:

ContentResolver contentResolver = context.getContentResolver();
String enabledNotificationListeners = Settings.Secure.getString(contentResolver, "enabled_notification_listeners");
String packageName = context.getPackageName();

// check to see if the enabledNotificationListeners String contains our package name
if (enabledNotificationListeners == null || !enabledNotificationListeners.contains(packageName))
{
    // in this situation we know that the user has not granted the app the Notification access permission
    throw new Exception();
}
else
{
    doSomethingThatRequiresNotificationAccessPermission();
}
Run Code Online (Sandbox Code Playgroud)

enabledNotificationsListeners Stringnull什么时候启用零通知侦听器,因此进行空检查.

我看到的典型值"" "com.woodblockwithoutco.remotecontrollerexample/com.woodblockwithoutco.remotecontrollerexample.RemoteControlService"看起来像这样:

  • 用户未提供任何应用通知访问权限
    • "com.scootrnova.android/com.scootrnova.android.ListenerService:com.woodblockwithoutco.remotecontrollerexample/com.woodblockwithoutco.remotecontrollerexample.RemoteControlService"(空NotificationManagerCompat.getEnabledListenerPackages(context);)
  • 用户已授予一个应用程序通知访问权限
    • Set<String>
  • 用户已授予两个应用程序通知访问权限
    • enabledNotificationsListeners

这个实现非常简单,效果很好:)

PS我有想法使用此答案中的硬编码"enabled_notification_listeners"字符串.

  • 在Android 6上,没有为任何应用程序启用通知侦听器,enabledNotificationListeners确实变为NULL. (3认同)
  • 这非常适合我.我唯一需要改变的是String packageName = context.getPackageName(); to**String packageName = MyService.class.getName();**因为我在我的启动器中检查它 (2认同)
  • NotificationManagerCompat.getEnabledListenerPackages(context)对SO进行检查的最佳解决方案。感谢您更新答案。 (2认同)

小智 29

我是Krome的开发者.我做了什么来检查是否启用了服务是添加公共静态变量,在onBind方法中变为true,在unbind中变为false.这就是这项服务的工作方式.

编辑:

public static boolean isNotificationAccessEnabled = false;

@Override
public void onListenerConnected() {
    isNotificationAccessEnabled = true;
}

@Override
public void onListenerDisconnected() {
    isNotificationAccessEnabled = false;
}
Run Code Online (Sandbox Code Playgroud)

  • 对于其他感兴趣的人来说,这是我的代码:`public static boolean isNotificationAccessEnabled = false; @Override public IBinder onBind(Intent mIntent){IBinder mIBinder = super.onBind(mIntent); isNotificationAccessEnabled = true; 返回mIBinder; } @Override public boolean onUnbind(Intent mIntent){boolean mOnUnbind = super.onUnbind(mIntent); isNotificationAccessEnabled = false; return mOnUnbind; 在我的主要活动中结合检查isNotificationAccessEnabled. (7认同)
  • 此解决方案仅在您第一次检查时才起作用,因为系统只对NotificationListenerService调用onBind回调一次.如果您尝试取消选中(将调用onUnbind)然后再次检查,则不会再次调用onBind,因此`isNotificationAcessAnabled`将为false. (2认同)
  • 这不是一个可靠的解决方案.Android大部分时间都会调用onBind/onUnbind,但根据Android框架团队的设计不是100%:https://groups.google.com/forum/#!msg/installer -Developers/2IegSgtGxyE/iXP3lBCH5SsJ (2认同)