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);
}
}
@Chuque
Copy link

Chuque commented May 8, 2018

It only works the first time we start the app and give the notification permission. But the second time, with permission already enabled, it simply dont connect to the service. How to fix this pleaseee?

@jecorrales3
Copy link

Hi bro, could you find an answer for this?

@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