Skip to content

Instantly share code, notes, and snippets.

@paulo-raca
Last active April 13, 2022 01:02
Show Gist options
  • Save paulo-raca/471680c0fe4d8f91b8cde486039b0dcd to your computer and use it in GitHub Desktop.
Save paulo-raca/471680c0fe4d8f91b8cde486039b0dcd to your computer and use it in GitHub Desktop.
getActiveNotifications() using NotificationListenerService
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="testapp.android.gradle.inutilfutil.com.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<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=".MyNotificationService"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
</application>
</manifest>
package testapp.android.gradle.inutilfutil.com.myapplication;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Intent;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
private static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onStart() {
showNotifications();
super.onStart();
}
@Override
public void onResume() {
showNotifications();
super.onResume();
}
public void showNotifications() {
if (isNotificationServiceEnabled()) {
Log.i(TAG, "Notification enabled -- trying to fetch it");
getNotifications();
} else {
Log.i(TAG, "Notification disabled -- Opening settings");
startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS));
}
}
public void getNotifications() {
Log.i(TAG, "Waiting for MyNotificationService");
MyNotificationService myNotificationService = MyNotificationService.get();
Log.i(TAG, "Active Notifications: [");
for (StatusBarNotification notification : myNotificationService.getActiveNotifications()) {
Log.i(TAG, " " + notification.getPackageName() + " / " + notification.getTag());
}
Log.i(TAG, "]");
}
private boolean isNotificationServiceEnabled(){
String pkgName = getPackageName();
final String allNames = Settings.Secure.getString(getContentResolver(), "enabled_notification_listeners");
if (allNames != null && !allNames.isEmpty()) {
for (String name : allNames.split(":")) {
if (getPackageName().equals(ComponentName.unflattenFromString(name).getPackageName())) {
return true;
}
}
}
return false;
}
}
package testapp.android.gradle.inutilfutil.com.myapplication;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import java.util.concurrent.Semaphore;
public class MyNotificationService extends NotificationListenerService {
private static final String TAG = "MyNotificationService";
static MyNotificationService _this;
static Semaphore sem = new Semaphore(0);
public static MyNotificationService get() {
sem.acquireUninterruptibly();
MyNotificationService ret = _this;
sem.release();
return ret;
}
@Override
public void onListenerConnected() {
Log.i(TAG, "Connected");
_this = this;
sem.release();
}
@Override
public void onListenerDisconnected() {
Log.i(TAG, "Disconnected");
sem.acquireUninterruptibly();
_this = null;
}
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
super.onNotificationRemoved(sbn);
}
}
@paulo-raca
Copy link
Author

I have absolutely no memory of writing this, or why 🤣

I took a look at it briefly -- Have you tried requestRebind()? -- https://developer.android.com/reference/android/service/notification/NotificationListenerService.html#requestRebind(android.content.ComponentName)

Alternatively, the implementation seems to be exactly the same as calling NotificationManager.getActiveNotifications() -- I imagine that enabling the NotificationService adds the missing permissions to the package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment