Android NotificationListenerService Example
Introduction
NotificationListenerService is introduced in Android 4.3 (API 18). It allows an application to receive information about notifications as it creates or removes. NotificationListenerService class is derived from the Service class. It has two abstract methods namely 1. onNotificationPosted 2. onNotificationRemoved.
To use NotificationListenerService, we need to create a java file which extends NotificationListenerService and implement two callback methods. Both methods have a parameter named “sbn”, which is an object of StatusBarNotification class. StatusBarNotification provides necessary information about Notifications.
NotificationListenerService provides facility to fetch active notifications using getActiveNotifications and also provides a feature to remove notifications using cancelAllNotifications.
Useful Methods
NotificationListenerService
onNotificationPosted()
onNotificationRemoved()
cancelAllNotifications()
getActiveNotifications()StatusBarNotification
getId()
getNotification()
getPackageName()
getPostTime()
isClearable()
isOngoing()
Note: User require to enable notification permission from “Settings > Security > Notification access”.
Source Code of NotificationListenerService
Worth to see the source code, If you hare curious. It has two java files and two AIDL files: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/service/notification
Example
This is simple example of NotificationListenerService, It has simple UI contain three buttons and one textview.
- Create Notification – It will create simple notification so that we can test onNotificationPosted event
- Clear All Notification – It will create all notification in notificationbar
- List of Notification – It will display notification list in textview
- TextView – display notification events and list of notification.
This example has Activity, Service and BroadcastReceiver. BroadcastReceiver used for communication between activity and service. We can’t access cancelAllNotifications() and getActiveNotifications() methods from activity directly so I use BroadcastReceivers.
Screenshots
Source Code
1. MainActivity.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | package com.kpbird.nlsexample; import android.app.Activity; import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.view.View; import android.widget.TextView; public class MainActivity extends Activity { private TextView txtView; private NotificationReceiver nReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtView = (TextView) findViewById(R.id.textView); nReceiver = new NotificationReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE" ); registerReceiver(nReceiver,filter); } @Override protected void onDestroy() { super .onDestroy(); unregisterReceiver(nReceiver); } public void buttonClicked(View v){ if (v.getId() == R.id.btnCreateNotify){ NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationCompat.Builder ncomp = new NotificationCompat.Builder( this ); ncomp.setContentTitle( "My Notification" ); ncomp.setContentText( "Notification Listener Service Example" ); ncomp.setTicker( "Notification Listener Service Example" ); ncomp.setSmallIcon(R.drawable.ic_launcher); ncomp.setAutoCancel( true ); nManager.notify(( int )System.currentTimeMillis(),ncomp.build()); } else if (v.getId() == R.id.btnClearNotify){ Intent i = new Intent( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE" ); i.putExtra( "command" , "clearall" ); sendBroadcast(i); } else if (v.getId() == R.id.btnListNotify){ Intent i = new Intent( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE" ); i.putExtra( "command" , "list" ); sendBroadcast(i); } } class NotificationReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { String temp = intent.getStringExtra( "notification_event" ) + "n" + txtView.getText(); txtView.setText(temp); } } } |
2. NLService.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | package com.kpbird.nlsexample; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.Log; public class NLService extends NotificationListenerService { private String TAG = this .getClass().getSimpleName(); private NLServiceReceiver nlservicereciver; @Override public void onCreate() { super .onCreate(); nlservicereciver = new NLServiceReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE" ); registerReceiver(nlservicereciver,filter); } @Override public void onDestroy() { super .onDestroy(); unregisterReceiver(nlservicereciver); } @Override public void onNotificationPosted(StatusBarNotification sbn) { Log.i(TAG, "********** onNotificationPosted" ); Log.i(TAG, "ID :" + sbn.getId() + "t" + sbn.getNotification().tickerText + "t" + sbn.getPackageName()); Intent i = new Intent( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE" ); i.putExtra( "notification_event" , "onNotificationPosted :" + sbn.getPackageName() + "n" ); sendBroadcast(i); } @Override public void onNotificationRemoved(StatusBarNotification sbn) { Log.i(TAG, "********** onNOtificationRemoved" ); Log.i(TAG, "ID :" + sbn.getId() + "t" + sbn.getNotification().tickerText + "t" + sbn.getPackageName()); Intent i = new Intent( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE" ); i.putExtra( "notification_event" , "onNotificationRemoved :" + sbn.getPackageName() + "n" ); sendBroadcast(i); } class NLServiceReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if (intent.getStringExtra( "command" ).equals( "clearall" )){ NLService. this .cancelAllNotifications(); } else if (intent.getStringExtra( "command" ).equals( "list" )){ Intent i1 = new Intent( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE" ); i1.putExtra( "notification_event" , "=====================" ); sendBroadcast(i1); int i= 1 ; for (StatusBarNotification sbn : NLService. this .getActiveNotifications()) { Intent i2 = new Intent( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE" ); i2.putExtra( "notification_event" ,i + " " + sbn.getPackageName() + "n" ); sendBroadcast(i2); i++; } Intent i3 = new Intent( "com.kpbird.nlsexample.NOTIFICATION_LISTENER_EXAMPLE" ); i3.putExtra( "notification_event" , "===== Notification List ====" ); sendBroadcast(i3); } } } } |
3. activity_main.xml
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | android:layout_width = "match_parent" android:layout_height = "match_parent" android:paddingLeft = "@dimen/activity_horizontal_margin" android:paddingRight = "@dimen/activity_horizontal_margin" android:paddingTop = "@dimen/activity_vertical_margin" android:paddingBottom = "@dimen/activity_vertical_margin" tools:context = ".MainActivity" > < Button android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Create Notification" android:id = "@+id/btnCreateNotify" android:onClick = "buttonClicked" android:layout_alignParentTop = "true" android:layout_alignParentLeft = "true" android:layout_alignParentRight = "true" /> < Button android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Clear All Notification" android:id = "@+id/btnClearNotify" android:onClick = "buttonClicked" android:layout_below = "@+id/btnCreateNotify" android:layout_alignLeft = "@+id/btnCreateNotify" android:layout_alignRight = "@+id/btnCreateNotify" /> < ScrollView android:layout_width = "match_parent" android:layout_height = "match_parent" android:layout_alignParentBottom = "true" android:layout_alignRight = "@+id/btnListNotify" android:layout_below = "@+id/btnListNotify" android:layout_alignLeft = "@+id/btnListNotify" > < TextView android:layout_width = "match_parent" android:layout_height = "wrap_content" android:textAppearance = "?android:attr/textAppearanceMedium" android:text = "NotificationListenerService Example" android:id = "@+id/textView" /> </ ScrollView > < Button android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "List of Notification" android:id = "@+id/btnListNotify" android:onClick = "buttonClicked" android:layout_below = "@+id/btnClearNotify" android:layout_alignLeft = "@+id/btnClearNotify" android:layout_alignRight = "@+id/btnClearNotify" /> </ RelativeLayout > |
4. AndroidManifest.xml
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <? xml version = "1.0" encoding = "utf-8" ?> package = "com.kpbird.nlsexample" android:versionCode = "1" android:versionName = "1.0" > < uses-sdk android:minSdkVersion = "18" android:targetSdkVersion = "18" /> < application android:allowBackup = "true" android:icon = "@drawable/ic_launcher" android:label = "@string/app_name" android:theme = "@style/AppTheme" > < activity android:name = "com.kpbird.nlsexample.MainActivity" android:label = "@string/app_name" android:screenOrientation = "portrait" > < intent-filter > < action android:name = "android.intent.action.MAIN" /> < category android:name = "android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > < service android:name = "com.kpbird.nlsexample.NLService" android:label = "@string/app_name" android:permission = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" > < intent-filter > < action android:name = "android.service.notification.NotificationListenerService" /> </ intent-filter > </ service > </ application > </ manifest > |
User following code to open Notification Access setting screen
1 2 | Intent intent= new Intent( "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS" ); startActivity(intent); |
I have runed on Android 4.3, but function onNotificationPosted and onNotificationRemoved don’t run when I create a notification message.
In MainActivity , I have added “startService(new Intent(MainActivity.this, NLService.class));” to start service.
Yeah, I confirm what chenxiang says.. The buttons ‘clear all notification’ and ‘list of notification’ don’t work. Anyone found a solution?
I aaded the startservice like as chenxiang says and i get
03-16 17:53:55.191: E/AndroidRuntime(16120): FATAL EXCEPTION: main
03-16 17:53:55.191: E/AndroidRuntime(16120): java.lang.RuntimeException: Error receiving broadcast Intent { act=com.kpbird.nlsexample.NOTIFICATION_LISTENER_SERVICE_EXAMPLE flg=0x10 (has extras) } in com.kpbird.nlsexample.NLService$NLServiceReceiver@42bc1468
(im using ADT eclipse)
Hi,I would like to know how to show package icon on left of each notification ?
For those not getting the app to work on their android phone or emulator, add this line of code to the bottom lines of the onCreate method of MainActivity.Java:
Intent intent=new Intent(“android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS”);
startActivity(intent);
This opens the notifications settings. Allow the app to manage notifications. Click ok on the warning.
MainActivity.Java onCreate should look like this:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtView = (TextView) findViewById(R.id.textView);
nReceiver = new NotificationReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(“nl.jeroenkarelkoster.notificationsblocker.NOTIFICATION_LISTENER_EXAMPLE”);
registerReceiver(nReceiver, filter);
Intent intent=new Intent(“android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS”);
startActivity(intent);
}
Is their any possibility that we can stop all the notifications from other apps?
nice
thank you