13

I'm using this code to open Notification Listener Settings:

startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));

I would like to check if the user has granted authorization to my app. I already tried to check if my NotificationListenerService is running, but it seems that it gets halted and restarted by the system (even if I return START_STICKY).

stepic
  • 673
  • 9
  • 19

5 Answers5

33

The only correct way to do it is to check the secure settings:

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());
AChep
  • 787
  • 6
  • 10
  • 2
    I really wanna give you a cookie! Gracias. – Olayinka May 09 '15 at 21:22
  • 1
    This works. You can check your AccessibilityService this way too, but by passing `"enabled_accessibility_services"` to `Settings.Secure.getString()`. Both strings are set as constants in Settings.Secure, but the one for notifications is hidden for some reason. – Steve Blackwell Sep 30 '15 at 00:07
  • Not working. while it's already approved - this code returns false – Udi Oshi Jul 30 '18 at 08:33
6

I was wrong, checking if service is running works:

    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;
    }
stepic
  • 673
  • 9
  • 19
  • 4
    If you uncheck the permission, the process keeps running. So this isn't bulletproof, but I haven't found another way. – black Apr 03 '14 at 12:07
  • 2
    If I uncheck the permission, my service gets destroyed. So the above answer works perfectly for me. – MrMaffen May 27 '14 at 13:54
5

If you're using androidx you can use

NotificationManagerCompat.getEnabledListenerPackages(Context context)

to check if your listener is enabled. Source

AsterixR
  • 547
  • 7
  • 9
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
    }
}
Fahad Alotaibi
  • 416
  • 3
  • 9
0

Saw this while browsing through the documentation inside android studio

Read only list of the service components that the current user has explicitly allowed to see all of the user's notifications, separated by ':'.

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

Hence made this up and added to a publicly accessible class

 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
    }

I have tested for above API above 27 , test it for below 27 before you go to production

metvsk
  • 189
  • 2
  • 4