Android Question Notification Listener from "Example of #Extends in Service"

wes58

Active Member
Licensed User
Longtime User
I have been trying to use #Extends Attribute, and I found this thread with Notification Listener library https://www.b4x.com/android/forum/threads/example-of-extends-in-service.74880/#content
I added to the example a code to clear one notification:
B4X:
Sub Clear(sbn As StatusBarNotification)
    listener.ClearNotification(sbn)
End Sub
Where sbn is a StatusBarNotification received in sub Listener_NotificationPosted(SBN As StatusBarNotification)
When I try to clear one notification, I get this error:
B4X:
notificationservice_clear (java line: 130)
java.lang.RuntimeException: java.lang.IllegalArgumentException: Expected receiver of type android.service.notification.NotificationListenerService, but got anywheresoftware.b4a.objects.NotificationListenerWrapper$NotificationListener
    at anywheresoftware.b4a.objects.NotificationListenerWrapper$NotificationListener.ClearNotification(NotificationListenerWrapper.java:90)
    at b4a.notificationlistener.notificationservice._clear(notificationservice.java:130)
It's probably a question for Erel, since he made this library for this example. But anyone is welcome with any suggestions.
 

wes58

Active Member
Licensed User
Longtime User
Is this the full error message?
I though that this is the most important part.
But here is the full message.
B4X:
notificationservice_clear (java line: 130)
java.lang.RuntimeException: java.lang.IllegalArgumentException: Expected receiver of type android.service.notification.NotificationListenerService, but got anywheresoftware.b4a.objects.NotificationListenerWrapper$NotificationListener
    at anywheresoftware.b4a.objects.NotificationListenerWrapper$NotificationListener.ClearNotification(NotificationListenerWrapper.java:84)
    at b4a.notificationlistener.notificationservice._clear(notificationservice.java:130)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)
    at anywheresoftware.b4a.keywords.Common$11.run(Common.java:1179)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7032)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: java.lang.IllegalArgumentException: Expected receiver of type android.service.notification.NotificationListenerService, but got anywheresoftware.b4a.objects.NotificationListenerWrapper$NotificationListener
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.objects.NotificationListenerWrapper$NotificationListener.ClearNotification(NotificationListenerWrapper.java:82)
    ... 11 more

And here is the code just for testing, that calls the sub in the Notificationservice:
sbnlist is a List to which sbn notifications posted are added to in the Listener_NotificationPosted sub
B4X:
Sub btnClear_Click
    Dim i As Int
    Dim j As Int
    j = EditText1.Text
    Log("size " & sbnlist.Size)
    If sbnlist.Size > 0 Then
        For i = 0 To sbnlist.Size-1
            Dim sbn As StatusBarNotification
            sbn = sbnlist.Get(i)
            Log("i " & i & " j " & j & " sbnid " & sbn.Id & " " & sbn.PackageName)
            If j = sbn.Id Then
                CallSubDelayed2(NotificationService, "Clear", sbn)
                Exit
            End If
        Next
    End If
End Sub
 
Last edited:
Upvote 0

wes58

Active Member
Licensed User
Longtime User
Is there any advantage of clearing the way you do in your java library - i.e. ClearNotification(sbn), instead of clearing by an sbn.id like this?
B4X:
    /**
     * clear one notification with ID
     */
    public  void  ClearNotificationID(int id){
            Context context = BA.applicationContext;
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.cancel(id);
    }
This code works.

I still would like to know how to fix this error, if possible.
 
Upvote 0

wes58

Active Member
Licensed User
Longtime User
What is the output of:
B4X:
Sub Clear(sbn As StatusBarNotification)
    Log(sbn)
    Log(GetType(sbn))
    listener.ClearNotification(sbn)
End Sub
Here it is:
B4X:
sbn = (StatusBarNotification) StatusBarNotification(pkg=b4a.notificationlistener user=UserHandle{0} id=5 tag=null key=0|b4a.notificationlistener|5|null|10385: Notification(channel=channel_3 pri=0 contentView=null vibrate=default sound=default defaults=0xffffffff flags=0x0 color=0x00000000 vis=PRIVATE semFlags=0x0 semPriority=0 semMissedCount=0))
GetType(sbn) = android.service.notification.StatusBarNotification
notificationservice_clear (java line: 134)
java.lang.RuntimeException: java.lang.IllegalArgumentException: Expected receiver of type android.service.notification.NotificationListenerService, but got anywheresoftware.b4a.objects.NotificationListenerWrapper$NotificationListener
    at anywheresoftware.b4a.objects.NotificationListenerWrapper$NotificationListener.ClearNotification(NotificationListenerWrapper.java:84)
    at b4a.notificationlistener.notificationservice._clear(notificationservice.java:134)
    at java.lang.reflect.Method.invoke(Native Method)
 
Upvote 0

wes58

Active Member
Licensed User
Longtime User
Since I didn't get a solution and the method of clearing the notification that I posted in post #4, only allows you to clear your own notifications I had to find the solution to the bug in the library posted in https://www.b4x.com/android/forum/threads/example-of-extends-in-service.74880/#content myself.
Unfortunately to do it I had to decompile the library to see the source code. The function to clear notification - public void ClearNotification(StatusBarNotificationWrapper SBN) - is located in NotificationListener class.
The function is like this:
B4X:
public void ClearNotification(StatusBarNotificationWrapper SBN) {
        StatusBarNotification sbn = (StatusBarNotification) SBN.getObject();
        if (VERSION.SDK_INT >= 21) {
            try {
                String key = (String) sbn.getClass().getMethod("getKey").invoke(sbn);
                this.owner.getClass().getMethod("cancelNotification", String.class).invoke(this, key);
            } catch (Exception var4) {
                throw new RuntimeException(var4);
            }
        } else {
            this.owner.cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
        }

    }
The error message indicated RuntimeException that occurred in try-catch.
This meant that the problem was, that this function should be in NotificationListenerWrapper extends NotificationListenerService class.
So to fix it, I put in NotificationListenerWrapper extends NotificationListenerService class, function
B4X:
public void ClearNotification(StatusBarNotification SBN) {                             //changed from StatusBarNotificationWrapper to StatusBarNotification
        StatusBarNotification sbn = (StatusBarNotification) SBN.getObject();
        if (VERSION.SDK_INT >= 21) {
            try {
                String key = (String) sbn.getClass().getMethod("getKey").invoke(sbn);
                this.getClass().getMethod("cancelNotification", String.class).invoke(this, key);
            } catch (Exception var4) {
                throw new RuntimeException(var4);
            }
        } else {
            this.cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());
        }

    }

and in NotificationListener class function:
B4X:
public void ClearNotification(StatusBarNotificationWrapper SBN) {
        StatusBarNotification sbn = (StatusBarNotification) SBN.getObject();
        owner.ClearNotification(SBN);
    }
That's it.
 
Last edited:
Upvote 0
Top