Background
I'm working on an app that requires to have notification-access permission, which is handled by the NotificationListenerService.
To request this special permission (which isn't a runtime permission), you can open its settings screen via the Intent of ACTION_NOTIFICATION_LISTENER_SETTINGS or ACTION_NOTIFICATION_LISTENER_DETAIL_SETTINGS.
The problem
There are 2 ways to see the status of NotificationListenerService:
- Query whether the permission is granted, using:
fun isNotificationServiceEnabled(context: Context): Boolean =
NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName)
- Once onListenerConnected callback is called (till onListenerDisconnected is called), it should mean that the service is active and is monitoring the notifications:
Implement this method to learn about when the listener is enabled and connected to the notification manager. You are safe to call getActiveNotifications() at this time.
The problem is that I've found a bug on Android, that shows that onListenerConnected is not reliable, meaning it might get called even when the permission isn't granted yet (to reproduce, grant the permission, uninstall and re-install).
So as opposed to the documentation, I can't get the list of active notifications there in this case.
What I've tried
I've reported this bug (here, including a sample and video to show it), and also tried to find alternatives:
In the
NotificationListenerServiceclass itself there is no other callback or series of events to show that it's indeed monitoring notifications.I tried to unbind/stop the service if
onListenerConnectedis called yet the permission isn't granted, hoping it will get bound again, but that didn't help.When this bug occurs, both
onListenerConnectedandonNotificationPostedwon't be called once the permission is actually granted for older notifications. Only new notifications will triggeronNotificationPosted. I was hoping that if I detect the issue, I could just rely on some notification the app has to trigger it, so that I could detect when the permission is granted.I tried to snooze a notification before the issue starts (meaning when the permission is still granted), hoping it would come back once I deny the permission or remove the app. Sadly it stayed snoozed.
I tried to find some callback using AppOpsManager.startWatchingMode, but while it can monitor various permissions (all start with "OPSTR_" in
AppOpsManagerclass), it doesn't have one for notification access, probably because it can only handle runtime permissions...I've tried to disable&re-enable the class using PackageManager.setComponentEnabledSetting, but it didn't help either.
The only workaround I can think of that is reliable, is to poll-query whether I got the permission or not, as soon as I detect the issue. I can probably do it because the
NotificationListenerServiceis considered to always-run (like a foreground service, not sure if it truly is) But this is not a nice way to solve it...
The question
Is there a more official way to monitor this special permission? To have a callback when it truly is granted ?