Android Question BatteryChanged event fires every few seconds

Rusty

Well-Known Member
Licensed User
Longtime User
I have implemented PhoneEvents and set up an event handler for the batterychanged event.
However, the event fires about every 10 seconds but the values don't change. It's been running for over 30 minutes and has consistently shown 14%, no change.
11:43:31 The battery level is: 14 Scale: 100 Plugged: true
11:43:33 The battery level is: 14 Scale: 100 Plugged: true
11:43:43 The battery level is: 14 Scale: 100 Plugged: true
11:43:44 The battery level is: 14 Scale: 100 Plugged: true
11:43:45 The battery level is: 14 Scale: 100 Plugged: true
11:43:45 The battery level is: 14 Scale: 100 Plugged: true
...
12:11:14 The battery level is: 14 Scale: 100 Plugged: true

B4X:
Sub Process_Globals

End Sub

Sub Globals
    Dim PE As PhoneEvents
       Dim Phone1 As Phone
       Dim Phone2 As PhoneWakeState
End Sub

Sub Activity_Create(FirstTime As Boolean)
    PE.Initialize("PhEvents") 
    Log(DateTime.Time(DateTime.Now) & "  Activity Start")
End Sub

Sub Activity_Touch (Action As Int, X As Float, Y As Float)
    Log(DateTime.Time(DateTime.Now) & "  Screen touched")
    ScreenAwake 
End Sub

Sub PhEvents_BatteryChanged (Level As Int, Scale As Int, Plugged As Boolean, Intent As Intent)
    Log(DateTime.Time(DateTime.Now) & "   The battery level is: " & Level & "   Scale: " & Scale & "  Plugged: " & Plugged)
End Sub

Sub Activity_Resume
    ToastMessageShow("activity resume",True)
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    ToastMessageShow("activity pause",True)
End Sub

Sub ScreenAwake
    ToastMessageShow("Awake sub called", False)
    Phone1.SetScreenBrightness(-1)
    Phone2.ReleaseKeepAlive
    Phone2.KeepAlive(True)
End Sub

Sub ScreenSleep
    ToastMessageShow("Sleep sub called", False)
    Phone2.ReleaseKeepAlive
    Phone1.SetScreenBrightness(0)
    Log("Screen sleep")
End Sub

Note: it is plugged in but the tablet is apparently discharging as fast as it is charging, so the level isn't changing.

Is it normal for it to fire when no changes in battery have (apparently) occurred?
 

Del

Member
Licensed User
Longtime User
I moved my battery level code to the Starter service but _BatteryChanged still gets fired at least once per second even though the Level does not change.

Is this a bug in the PhoneEvents library ?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
So the OS knows the name of the B4A event handler ?
No. the OS is firing the events, your app has registered itself to receive the events and the PhoneEvents are getting the Event to handle it
 
Upvote 0

Del

Member
Licensed User
Longtime User
If you want to get battery level here is the solution that I found before.

https://www.b4x.com/android/forum/threads/solved-i-need-to-get-battery-level.51854/

How is this different from the code in post 1 ?

It seems wrong to me that this event fires ~once per second for something so trivial and in any case it messes up my debugging.

I had the idea that in the Starter service I could put .StopListening (or = Null or something) in the _BatteryChanged event and then PhoneEvents.Initialize in a timer tick event fired every five minutes. ( .StartListening does not exist)

However the timer event in the Starter does not happen.

Two questions therefore :-
Is there an issue with Timers in Starter services or in services generally ?
Is the approach using a timer and .StopListening etc worth pursuing ?
 
Last edited:
Upvote 0

boralogy

Member
Licensed User
Longtime User
How is this different from the code in post 1 ?

It seems wrong to me that this event fires ~once per second for something so trivial and in any case it messes up my debugging.

I had the idea that in the Starter service I could put .StopListening (or = Null or something) in the _BatteryChanged event and then PhoneEvents.Initialize in a timer tick event fired every five minutes. ( .StartListening does not exist)

However the timer event in the Starter does not happen.

Two questions therefore :-
Is there an issue with Timers in Starter services or in services generally ?
Is the approach using a timer and .StopListening etc worth pursuing ?


I will find project from my archive then I will upload here so you can make tests on it.
 
Upvote 0

rickbonnell

New Member
Licensed User
Longtime User
I will find project from my archive then I will upload here so you can make tests on it.
This may be useful for somebody. Instead of using a receiver, I am running a scheduled service that checks for the last value of ACTION_BATTERY_CHANGED. Got this from several stack overflow posts. Requires JavaObject library.
B4X:
#Region  Service Attributes 
    #StartAtBoot: False
   
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
Private NativeMe As JavaObject
Dim b As Beeper
Dim Notif As Int
End Sub

Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.
NativeMe.InitializeContext
b.Initialize(700,700)
End Sub

Sub Service_Start (StartingIntent As Intent)
StartServiceAt("", DateTime.Now + 8000,False)
Notif = 0
Dim status As Int = NativeMe.RunMethod("getBatteryStatus", Null)
Dim status2 As Int = NativeMe.RunMethod("getBatteryStatus2", Null)
Dim status3 As Int = NativeMe.RunMethod("isScreenLocked", Null)
Dim status4 As Int = NativeMe.RunMethod("isScreenOn", Null)
'Log("Charging status= "& status)
'Log("Charge Level =" & status2)
'Log("Screen Locked =" & status3)
'Log("Screen on =" & status4)
If status =5 Then 
    Notif =1
End If
If status =2 And status2 = 1 Then
    Notif = 1
End If
If Notif =1 And status4 = 1 And status3 = 0 Then
    ToastMessageShow("Device is fully charged. Please unplug.", True)
    b.Beep
End If
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Service_Destroy

End Sub

#if JAVA
import android.os.BatteryManager;
import android.content.Context;
import android.content.IntentFilter;
import android.content.Intent;
import android.app.KeyguardManager;
import android.os.PowerManager;
public int getBatteryStatus(){
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = getApplicationContext().registerReceiver(null, ifilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);

return status;
}
public int getBatteryStatus2(){
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = getApplicationContext().registerReceiver(null, ifilter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

int batteryPct = level / scale;

return batteryPct;
}
public int isScreenLocked(){
int myint = 0;
KeyguardManager myKM = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
boolean mybool= myKM.inKeyguardRestrictedInputMode ();
if (mybool==true) myint=1;
return myint;
}
public int isScreenOn(){
int myint = 0;
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
boolean mybool2 = pm.isScreenOn();
if (mybool2==true) myint=1;
return myint;
}
#end if
 
Upvote 0
Top