Android Tutorial NotificationListener library implementation tutorial

Erel

B4X founder
Staff member
Licensed User
Longtime User
The NotificationListener library wraps a new feature introduced in Android 4.3: NotificationListener library (NotificationListenerService)

This library is built a bit different than most libraries. The main reason is that this feature is implemented as a service which we need to subclass.

The design is:
- The library includes a service named anywheresoftware.b4a.objects.NotificationListenerWrapper. This class is hidden with the @Hide annotation. This is the service that subclasses NotificationListenerService.

The user will need to manually add the service definition with the manifest editor. See the tutorial above for more information.

Note that there are two inner classes in this class.

The question is how to interact with this service? There are two types of interactions in this case. The service needs to raise events and we need to send commands to the service when we want to clear the notifications.

The interaction is done with intents in this case. The user must create a service named NotificationService. This makes it simple to send intents from the main service:
B4X:
private Intent createIntent(String event, StatusBarNotification sbn) throws ClassNotFoundException {
     Intent i;
     i = new Intent(this, Class.forName(getPackageName() + ".notificationservice")); //the name is lower cased
     i.setAction("b4a_notificationlistener");
     i.putExtra("sbn", sbn);
     i.putExtra("event", event);
     return i;
   }

For example:
B4X:
@Override
   public void onNotificationRemoved(StatusBarNotification arg0) {
       startService(createIntent("removed", arg0));
   }

The user is expected to create a NotificationListener object (one of the inner classes) and then call HandleIntent in Service_Start. HandleIntent checks whether this intent is indeed related to the notification listener and handles it:
B4X:
/**
      * Handles the intent with the notifications information.
      *Returns true if the intent was handled.
      */
     public boolean HandleIntent(IntentWrapper StartingIntent) {
       if (StartingIntent.IsInitialized() == false)
         return false;
       if (StartingIntent.getAction().equals("b4a_notificationlistener")) {
         String event = (String) StartingIntent.GetExtra("event");
         StatusBarNotification sbn = StartingIntent.getObject().getParcelableExtra("sbn");
         if (event.equals("posted")) {
           ba.raiseEvent(this, eventName + "_notificationposted", AbsObjectWrapper.ConvertToWrapper(
               new StatusBarNotificationWrapper(), sbn));
         }
         else if (event.equals("removed")) {
           ba.raiseEvent(this, eventName + "_notificationremoved", AbsObjectWrapper.ConvertToWrapper(
               new StatusBarNotificationWrapper(), sbn));
         }
        
         return true;
       }
       return false;
     }

This code in the main service responds to the user commands:
B4X:
@Override
   public int onStartCommand(Intent intent, int flags, int startId) {
     super.onStartCommand(intent, flags, startId);
     if (intent.hasExtra("b4a_cancel_all"))
       cancelAllNotifications();
     else if (intent.hasExtra("b4a_cancel")) {
       StatusBarNotification sbn = intent.getParcelableExtra("sbn");
       cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
     }
     return Service.START_NOT_STICKY;
   }

Interacting with intents is simple. We do not need to manage the B4A service lifecycle ourselves. The service will be created if it is not already running.

The complete source code is attached.
 

Attachments

  • NotificationListenerWrapper.zip
    1.6 KB · Views: 1,048

Theera

Well-Known Member
Licensed User
Longtime User
Thank you,Erel that you give me a source code too. I will pratice compile it compare with your library which you gave, in order to learn more.(protection: not forget stragy of how to create the library)
 
Top