Android Question Crash on void android.os.PowerManager$WakeLock.release()

FrankBerra

Active Member
Licensed User
Longtime User
Hello everyone!

On Firebase Console i receve many crashes like this:
B4X:
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.PowerManager$WakeLock.release()' on a null object reference
       at anywheresoftware.b4a.objects.ServiceHelper$StarterHelper.handleStartIntent(ServiceHelper.java:155)
       at test.me.broadcastreceiverservice.handleStart(broadcastreceiverservice.java:99)
       at test.me.broadcastreceiverservice.access$000(broadcastreceiverservice.java:8)
       at test.me.broadcastreceiverservice$2.run(broadcastreceiverservice.java:80)
       at android.os.Handler.handleCallback(Handler.java:907)
       at android.os.Handler.dispatchMessage(Handler.java:105)
       at android.os.Looper.loop(Looper.java:216)
       at android.app.ActivityThread.main(ActivityThread.java:7625)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

Here someone experienced the same problem: https://stackoverflow.com/questions/30336252/runtimeexception-android-os-powermanagerwakelockrelease
but since i am not a skilled programmer i can't understand what it is happening...

Is there anyone on B4A that faced the same problem and have some suggestions to fix it?

Thank you in advance!
 

FrankBerra

Active Member
Licensed User
Longtime User
This is the code of the BroadcastReceiverService if it can be useful:
B4X:
#Region  Service Attributes
   #StartAtBoot: True
  
#End Region

Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Dim BroadCast As BroadCastReceiver
   Dim ForegroundGiaAvviato As Boolean = False
End Sub

Sub Service_Create
   BroadCast.Initialize("BroadcastReceiver")
   BroadCast.addAction("android.net.conn.CONNECTIVITY_CHANGE")
   BroadCast.SetPriority(2147483647)
   BroadCast.registerReceiver("")
End Sub

Sub BroadcastReceiver_OnReceive (Action As String, i As Object) 'https://www.b4x.com/android/forum/threads/broadcastreceiver.12493/
   AvviaIlForeground
  
   Dim retIn As Intent
   retIn = i
   Dim IsConnected As String

   If Action = "android.net.conn.CONNECTIVITY_CHANGE" Then
       Dim jo As JavaObject = retIn
       If jo.IsInitialized Then
           Dim NetworkInfo As JavaObject = jo.RunMethod("getParcelableExtra", Array("networkInfo"))

           If NetworkInfo.IsInitialized Then
               IsConnected = NetworkInfo.RunMethod("getState", Null)

               If IsConnected.EqualsIgnoreCase("CONNECTED") Then
                   'ToastMessageShow("Connesso", False)
                   If (DateTime.Now - Starter.TickUltimoVoltaCheLaConnessioneEraDisponibile) > 2 * DateTime.TicksPerMinute Then
                       Starter.TickUltimoVoltaCheLaConnessioneEraDisponibile = DateTime.Now
                       CallSubDelayed(Starter, "Verifica_SeCiSonoDatiInLocaleDaInviareAlServer")
                   End If
               Else
                   'ToastMessageShow("Disconnesso", False)
               End If
           Else
               Starter.TickUltimoVoltaCheLaConnessioneEraDisponibile = DateTime.Now
               CallSubDelayed(Starter, "Verifica_SeCiSonoDatiInLocaleDaInviareAlServer")
           End If
       Else
           Starter.TickUltimoVoltaCheLaConnessioneEraDisponibile = DateTime.Now
           CallSubDelayed(Starter, "Verifica_SeCiSonoDatiInLocaleDaInviareAlServer")
       End If
  
   End If

   BroadCast.AbortBroadcast
  
   FermaIlForeground
End Sub

Sub Service_Start (StartingIntent As Intent)
   AvviaIlForeground
   StartServiceAt(Me, DateTime.Now + 10*DateTime.TicksPerMinute, True)
   FermaIlForeground
End Sub

Sub Service_Destroy

End Sub


Sub AvviaIlForeground
   If ForegroundGiaAvviato == False Then
       Dim n As Notification
       n.Initialize2(n.IMPORTANCE_LOW)
       n.Icon = "notifica_generica"
       n.Light = False
       n.Sound = False
       n.Vibrate = False
       Try
           n.SetInfo2(Starter.MappaEtichette.Get("NotificaDiSistema_check_Titolo"), Starter.MappaEtichette.Get("NotificaDiSistema_check_Testo"), "Visualizza_SpiegazioneNotificaGenerica", Main)
       Catch
           n.SetInfo2("Ever", "Loading...", "Visualizza_SpiegazioneNotificaGenerica", Main)
           CallSubDelayed2(Starter, "Logga_AnomaliaGestita", "Anomalia in AvviaIlForeground del BroadcastReceiverService")
       End Try
       Service.StartForeground(100, n)
      
       ForegroundGiaAvviato = True
   End If
End Sub

Sub FermaIlForeground
   Service.StopForeground(100)
   ForegroundGiaAvviato = False
End Sub
 
Last edited:
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
OK - so which line is the error at? Assuming you haven't changed any code in your BroadCastReceiverService, open the .java file in your projects Objects folder & look at line 99.

- Colin.
 
Upvote 0

FrankBerra

Active Member
Licensed User
Longtime User
Thanks for the hint. This is what i see:
B4X:
    private void handleStart(android.content.Intent intent) {
       BA.LogInfo("** Service (broadcastreceiverservice) Start **");
       java.lang.reflect.Method startEvent = processBA.htSubs.get("service_start");
       if (startEvent != null) {
           if (startEvent.getParameterTypes().length > 0) {
               anywheresoftware.b4a.objects.IntentWrapper iw = ServiceHelper.StarterHelper.handleStartIntent(intent, _service, processBA);  '<--- This is line n. 99
               processBA.raiseEvent(null, "service_start", iw);
           }
           else {
               processBA.raiseEvent(null, "service_start");
           }
       }
    }
...but it looks ununderstandable to me.
Any suggestion?
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Thanks for the hint. This is what i see:
B4X:
    private void handleStart(android.content.Intent intent) {
       BA.LogInfo("** Service (broadcastreceiverservice) Start **");
       java.lang.reflect.Method startEvent = processBA.htSubs.get("service_start");
       if (startEvent != null) {
           if (startEvent.getParameterTypes().length > 0) {
               anywheresoftware.b4a.objects.IntentWrapper iw = ServiceHelper.StarterHelper.handleStartIntent(intent, _service, processBA);  '<--- This is line n. 99
               processBA.raiseEvent(null, "service_start", iw);
           }
           else {
               processBA.raiseEvent(null, "service_start");
           }
       }
    }
...but it looks ununderstandable to me.
Any suggestion?

Hmmm - not sure. Do you previously set a WakeLock anywhere in your code? I'm wondering if you set a WakeLock in a previous instance of the service (or somewhere else in the app) & then when the service restarts it tries to release the WakeLock & the error is because the previous instance no longer exists? I'm pretty sure that releasing a WakeLock from within B4A doesn't cause an error if there isn't a WakeLock, but maybe this is happening in the background somewhere?

- Colin.
 
Upvote 0

FrankBerra

Active Member
Licensed User
Longtime User
I don't know what is a wakelock precisely, so i didn't set a wakelock intentionally. Maybe a library set it? When does a wakelock is used?
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
I don't know what is a wakelock precisely, so i didn't set a wakelock intentionally. Maybe a library set it? When does a wakelock is used?
https://developer.android.com/training/scheduling/wakelock

In the B4A IDE, click on the "Logs" tab, then click the "Permissions" button. If you see android.permission.WAKE_LOCK listed as one of the permissions, then something (possibly a library) is requiring it. Actually, I think if you are using a service &/or broadcast receiver, the permission is required.

Looking again at your code, I guess it's possible that you are calling Service.StartForeground(100, n) after your call to Service.StopForeground(100) - so maybe the service is already running when you try to restart it with the StartServiceAt.

In this code:
B4X:
Sub Service_Start (StartingIntent As Intent)
   AvviaIlForeground
   StartServiceAt(Me, DateTime.Now + 10*DateTime.TicksPerMinute, True)
   FermaIlForeground
End Sub
you might want to try using a Wait For to ensure that AvviaIForeground has completed before you call FermaIlForeground. Or you could just move the last 2 lines of the Service_Start to the end of your AvviaIForeground sub.

- Colin.
 
Upvote 0

FrankBerra

Active Member
Licensed User
Longtime User
Thank you for the suggestions! I will try to use Wait For.

Anyway i feel confused now: what is the difference between this version:
B4X:
   AvviaIlForeground
   StartServiceAt(Me, DateTime.Now + 10*DateTime.TicksPerMinute, True)
   FermaIlForeground

And this version:
B4X:
'---start of AvviaIlForeground
If ForegroundGiaAvviato == False Then
       Dim n As Notification
       n.Initialize2(n.IMPORTANCE_LOW)
       n.Icon = "notifica_generica"
       n.Light = False
       n.Sound = False
       n.Vibrate = False
       Try
           n.SetInfo2(Starter.MappaEtichette.Get("NotificaDiSistema_check_Titolo"), Starter.MappaEtichette.Get("NotificaDiSistema_check_Testo"), "Visualizza_SpiegazioneNotificaGenerica", Main)
       Catch
           n.SetInfo2("Ever", "Loading...", "Visualizza_SpiegazioneNotificaGenerica", Main)
           CallSubDelayed2(Starter, "Logga_AnomaliaGestita", "Anomalia in AvviaIlForeground del BroadcastReceiverService")
       End Try
       Service.StartForeground(100, n)
      
       ForegroundGiaAvviato = True
   End If
'---End of AvviaIlforeground

'---
StartServiceAt(Me, DateTime.Now + 10*DateTime.TicksPerMinute, True)
'---

'---Start of FermaIlForeground
Service.StopForeground(100)
   ForegroundGiaAvviato = False
'---stop of FermaIlForeground

In the second version all the instructions are executed sequentially one after the other in the same sub and in the first version aren't executed sequentially?
 
Last edited:
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Thank you for the suggestions! I will try to use Wait For.

Anyway i feel confused now: what is the difference between this version:
B4X:
   AvviaIlForeground
   StartServiceAt(Me, DateTime.Now + 10*DateTime.TicksPerMinute, True)
   FermaIlForeground

And this version:
B4X:
'---start of AvviaIlForeground
If ForegroundGiaAvviato == False Then
       Dim n As Notification
       n.Initialize2(n.IMPORTANCE_LOW)
       n.Icon = "notifica_generica"
       n.Light = False
       n.Sound = False
       n.Vibrate = False
       Try
           n.SetInfo2(Starter.MappaEtichette.Get("NotificaDiSistema_check_Titolo"), Starter.MappaEtichette.Get("NotificaDiSistema_check_Testo"), "Visualizza_SpiegazioneNotificaGenerica", Main)
       Catch
           n.SetInfo2("Evermet", "Loading...", "Visualizza_SpiegazioneNotificaGenerica", Main)
           CallSubDelayed2(Starter, "Logga_AnomaliaGestita", "Anomalia in AvviaIlForeground del BroadcastReceiverService")
       End Try
       Service.StartForeground(100, n)
     
       ForegroundGiaAvviato = True
   End If
'---End of AvviaIlforeground

'---
StartServiceAt(Me, DateTime.Now + 10*DateTime.TicksPerMinute, True)
'---

'---Start of FermaIlForeground
Service.StopForeground(100)
   ForegroundGiaAvviato = False
'---stop of FermaIlForeground

In the second version all the instructions are executed sequentially one after the other in the same sub and in the first version aren't executed sequentially?

Potentially, yes (I think :)). In the first version, if there is a delay in AvviaIForeground, the other 2 lines could be executed before AvviaIForeground finishes, or if Service.StartForeground is executed asynchronously the sub could exit before StartForeground completed & actually, the second version wouldn't work either (although I don't think this is the case because there's no callback for StartForeground & it doesn't return a value). Or it could just be that it takes some time for the service to actually start in the foreground.

- Colin.
 
Upvote 0
Top