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

Discussion in 'Android Questions' started by wes58, May 3, 2019.

  1. wes58

    wes58 Active Member Licensed 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:
    Code:
    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:
    Code:
    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.
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    Is this the full error message?
     
  3. wes58

    wes58 Active Member Licensed User

    I though that this is the most important part.
    But here is the full message.
    Code:
    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
    Code:
    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: May 3, 2019
  4. wes58

    wes58 Active Member Licensed 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?
    Code:
    /**
         * 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.
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    What is the output of:
    Code:
    Sub Clear(sbn As StatusBarNotification)
        
    Log(sbn)
        
    Log(GetType(sbn))
        listener.ClearNotification(sbn)
    End Sub
     
  6. wes58

    wes58 Active Member Licensed User

    Here it is:
    Code:
    sbn = (StatusBarNotificationStatusBarNotification(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)
     
  7. Erel

    Erel Administrator Staff Member Licensed User

    Might be a bug in the library. Can you upload the project?
     
  8. wes58

    wes58 Active Member Licensed User

  9. Erel

    Erel Administrator Staff Member Licensed User

    If possible please upload the project.
     
  10. wes58

    wes58 Active Member Licensed 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:
    Code:
    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
    Code:
    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:
    Code:
    public void ClearNotification(StatusBarNotificationWrapper SBN) {
            
    StatusBarNotification sbn = (StatusBarNotification) SBN.getObject();
            owner.ClearNotification(SBN);
        
    }
    That's it.
     
    Last edited: May 17, 2019
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice