Thursday, 2 August 2018

How to cancel an ongoing notification of another app?

Background

I've found an app that somehow hides heads-up notifications, including even ongoing notifications (used by foreground services), called NCleaner .
I was wondering how such a thing works.

The problem

There isn't much information of how to control notifications of other apps. Only of the current app, and for some reason I've failed to cancel an ongoing notification, but I've succeeded canceling a normal one.

What I've found

I've found this sample showing how to monitor notifications. After searching on the docs about NotificationListenerService, I've also found how to cancel specific notifications of other apps.
However, it doesn't work for ongoing notifications.
For testing of normal notifications I just sent myself an email or wrote something on PushBullet app via my PC.
For testing of ongoing notifications, I've installed and ran my spare time app (here), which shows an ongoing notification right on the beginning of the app, starting from Android O. In fact, it can even hide the notifications of the OS, of USB connected and debugging (just connect the device to the PC via USB) ...
Here's the code I've made, based on the sample, to cancel all notifications it gets:
NotificationListenerExampleService.kt
class NotificationListenerExampleService : NotificationListenerService() {

    override fun onNotificationPosted(sbn: StatusBarNotification) {
        Log.d("AppLog", "sbn:" + sbn.toString())
        cancelNotification(sbn.key)
    }

    override fun onListenerConnected() {
        super.onListenerConnected()
        Log.d("AppLog", "onListenerConnected")
    }

    override fun onNotificationRemoved(sbn: StatusBarNotification) {}
}

manifest:
<application
  android:allowBackup="true" android:icon="@mipmap/ic_launcher" 
android:label="@string/app_name" android:supportsRtl="true" android:theme=
"@style/AppTheme"
  tools:ignore="AllowBackup,GoogleAppIndexingWarning">
  <activity android:name=".MainActivity">
    <intent-filter>
      <action android:name="android.intent.action.MAIN"/>

      <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
  </activity>

  <service
    android:name=".NotificationListenerExampleService" android:label="
@string/service_label" android:permission="android.permission.BIND_NOTIFICATION
_LISTENER_SERVICE">
    <intent-filter>
      <action android:name="android.service.notification.NotificationListenerService"/>
    </intent-filter>
  </service>
</application>

MainActivity.kt
class MainActivity : AppCompatActivity() {

    private val isNotificationServiceEnabled: Boolean
        get() {
            val pkgName = packageName
            val flat = Settings.Secure.getString(contentResolver, "enabled_notification_
listeners"")
            if (!TextUtils.isEmpty(flat)) {
                val names = flat.split(":".toRegex()).dropLastWhile { it.isEmpty() }
.toTypedArray()
                for (i in names.indices) {
                    val cn = ComponentName.unflattenFromString(names[i])
                    if (cn != null) {
                        if (TextUtils.equals(pkgName, cn.packageName)) {
                            return true
                        }
                    }
                }
            }
            return false
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (!isNotificationServiceEnabled) {
            startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
        }
    }

}

The questions

  1. How come my code can't remove ongoing notifications?
  2. How come the app I've found can do it? What does it do?
  3. Just how much does this API provide in terms of notifications? Looking at the docs, it seems it can do a lot: read notifications, dismiss them, get all kinds of information about them, ... But I can't find some other features: Is it possible to modify a notification? To change its priority? To make it avoid being a heads-up-notification and just be in the notification drawer? Is it possible to trigger an action of a notification?


from How to cancel an ongoing notification of another app?

No comments:

Post a Comment