Android Question NotificationListerner on Android 4

Azam Memon

Member
Licensed User
Hi,

I have an optional feature in my app to listen to Notifications, I have used NotificationListener for that, which should be enabled only on API >=19 by the user and this option won't appear on API < 19. But when I run my app on android 4 (API < 19), I am getting an error, which is same on NotificationListner example code, the same error appears in my app. However, the app has no access to listen to notifications from notification listener settings of Android OS.

Log:
java.lang.RuntimeException: Unable to create service b4a.notificationlistener.starter: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2263)
    at android.app.ActivityThread.access$1600(ActivityThread.java:123)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at b4a.notificationlistener.starter.onCreate(starter.java:39)
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:2253)
    ... 10 more
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at b4a.notificationlistener.starter.onCreate(starter.java:37)
    ... 11 more
Caused by: java.lang.NoClassDefFoundError: b4a.notificationlistener.notificationservice
    at b4a.notificationlistener.main.initializeProcessGlobals(main.java:419)
    ... 14 more

Is there any workaround to disable loading process_globals of notificationListener on API < 19? The process_globals of each service and activity are loaded on app launch. I am using minSDK version of 11 and target Sdk as 29.
 

MarcoRome

Expert
Licensed User
Longtime User

This is a new feature which is only available on Android 4.3+ (api 18+)
 
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
B4X:
Sub Process_Globals
   Private listener As NotificationListener
End Sub
Sub Service_Create
    Dim sdkversion As Int
    Dim jo As JavaObject
    sdkversion = jo.InitializeStatic("android.os.Build$VERSION").GetField("SDK_INT")
    If sdkversion > 18 Then
       listener.Initialize("listener")
   ...........
End Sub
 
Upvote 0

Azam Memon

Member
Licensed User
B4X:
Sub Process_Globals
   Private listener As NotificationListener
End Sub
Sub Service_Create
    Dim sdkversion As Int
    Dim jo As JavaObject
    sdkversion = jo.InitializeStatic("android.os.Build$VERSION").GetField("SDK_INT")
    If sdkversion > 18 Then
       listener.Initialize("listener")
   ...........
End Sub

The problem is the "NotificationListener" service is not being executed. If you check my error log (post #1), the app crashes when main activity loads process_globals of all services and activities (also process_gloabals of notification service) and this crashes the app. I have even added a condition to not initialize NotificationListener as:

B4X:
Sub Process_Globals
    Dim p As Phone
    If p.SdkVersion > 18 Then
        Dim listener As NotificationListener
    End If
End Sub

I am not starting NotificationService with any code in any module but even then the app crashes at start, even the main activity is not being displayed.
 
Upvote 0

MarcoRome

Expert
Licensed User
Longtime User
Error:
.....
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at b4a.notificationlistener.starter.onCreate(starter.java:39)

Do you tried this way ?
B4X:
Sub Service_Create
    Dim sdkversion As Int
    Dim jo As JavaObject
    sdkversion = jo.InitializeStatic("android.os.Build$VERSION").GetField("SDK_INT")
    If sdkversion > 18 Then
       listener.Initialize("listener")
   ...........
End Sub
 
Upvote 0

Azam Memon

Member
Licensed User
Do you tried this way ?
B4X:
Sub Service_Create
Dim sdkversion As Int
Dim jo As JavaObject
sdkversion = jo.InitializeStatic("android.os.Build$VERSION").GetField("SDK_INT")
If sdkversion > 18 Then
listener.Initialize("listener")
...........
End Sub

I have tried same using phone.sdkVersion:

B4X:
If p.SdkVersion > 18 Then
    listener.Initialize("listener")
End If

and using your suggested code as well:
B4X:
Dim sdkversion As Int
Dim jo As JavaObject
sdkversion = jo.InitializeStatic("android.os.Build$VERSION").GetField("SDK_INT")
    

If sdkversion > 18 Then
    listener.Initialize("listener")
End If

But result is same.

Issue is somewhere here:
at b4a.notificationlistener.main.initializeProcessGlobals(main.java:419)

In java code of main.java line 419 (See attachment):
B4X:
notificationservice._process_globals();
is being called and this causes the error. I don't want to call this line when API < 19. But these process_globals of each activity and service are automatically called during the app launch.
 

Attachments

  • notification_listener.png
    notification_listener.png
    59.3 KB · Views: 178
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Try
B4X:
Sub Process_Globals
   Private listenerObject As Object
End Sub

Sub Service_Create
    Dim p As Phone
    If p.SdkVersion > 18 Then
        Dim listener As NotificationListener
       listener.Initialize("listener")
       listenerObject = listener
    End If
   ...........
End Sub

Then anywhere that you need to access listener you can do
B4X:
    Dim p As Phone
    If p.SdkVersion > 18 Then
        Dim listener As NotificationListener
       listener = listenerObject
       'do you stuff with the listener object as usual
    End If

Note: Untested.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Upvote 0

Azam Memon

Member
Licensed User
at b4a.notificationlistener.main.initializeProcessGlobals(main.java:419)

To solve this issue in main.java, I had tried to change line 419 from:

Main.java:
notificationservice._process_globals();

to:
B4X:
if(android.os.Build.VERSION.SDK_INT >= 18) {  notificationservice._process_globals(); }

using CustomBuildAction as:
B4X:
#CustomBuildAction: 2, C:\Users\Azam Rafique\Downloads\Compressed\NotificationListenerB4A\NotificationListener\Objects\replac.bat, "notificationservice._process_globals();" "if(android.os.Build.VERSION.SDK_INT >= 18) {  notificationservice._process_globals(); }" "src/b4a/notificationlistener" "\main.java"

Where replac.bat contains script to find and replace string in given file.

Now, I am getting another error in Activity.loadLayout line:

Error Log:
main_activity_create (java line: 342)
java.lang.NoClassDefFoundError: b4a/notificationlistener/notificationservice
    at java.lang.Class.getDeclaredFields(Native Method)
    at java.lang.Class.getDeclaredFields(Class.java:647)
    at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayoutHelper(LayoutBuilder.java:368)
    at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayoutHelper(LayoutBuilder.java:453)
    at anywheresoftware.b4a.keywords.LayoutBuilder.loadLayout(LayoutBuilder.java:148)
    at anywheresoftware.b4a.objects.ActivityWrapper.LoadLayout(ActivityWrapper.java:209)
    at b4a.notificationlistener.main._activity_create(main.java:342)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)
    at b4a.notificationlistener.main.afterFirstLayout(main.java:104)
    at b4a.notificationlistener.main.access$000(main.java:17)
    at b4a.notificationlistener.main$WaitForLayout.run(main.java:82)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: b4a.notificationlistener.notificationservice
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)

In file main.java line 342 is:
Main.java:
mostCurrent._activity.LoadLayout("1",mostCurrent.activityBA);

If I am commenting Activity.loadLayout line, then it works fine but doesn't show layout. Same issue on my actual working project, issue in that project is also in line activity.loadlayout.

Does anyone have a solution to this issue or any trick, please?
 
Upvote 0
Top