I have used Foreground Services to keep things going in the background and recently had to move to Android 14 (API 34). I'm starting the services from the App so don't need any clever way to start them in the background. The solution for me was simply to declare their usage in the manifest, then they seem to work as before. I think this is mainly to help the Playstore review process check that you're not trying to do anything dodgy.
AddPermission(android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE)
SetServiceAttribute(ServiceName, android:foregroundServiceType, "connectedDevice")
Here's what I have so far....
I decided to go with a Service since upon reading on Receivers, I noted that they are short lived or only used to run for a short period of time.
With that said, I did some testing last night, and I was able to run the service for around 2 hours until I had to stop it as I was ready to go to bed, here's what my manifest file looks like.
AddManifestText(
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34"/>
<supports-screens android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
CreateResourceFromFile(Macro, Themes.LightTheme)
'End of default text.
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.BLUETOOTH_SCAN)
AddPermission(android.permission.BLUETOOTH_CONNECT)
SetApplicationAttribute(android:largeHeap,"true")
AddManifestText(<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="19" />
)
AddPermission(android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE)
SetServiceAttribute(LogData, android:foregroundServiceType, "connectedDevice")
The code in my LogData Service
#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 usbmeter As Bitmap
End Sub
Sub Service_Create
Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_WHEN_NEEDED
usbmeter.Initialize(File.DirAssets, "fnb58.JPG")
Log("is service running: " & IsPaused(Me))
Service.StartForeground(1, Simple_Notification)
End Sub
Sub Service_Start (StartingIntent As Intent)
Service.StopAutomaticForeground 'Call this when the background task completes (if there is one)
End Sub
Sub Service_Destroy
'''Service.StopAutomaticForeground
StopService(Me)
Log("LogData Service destroyed...")
End Sub
Sub Simple_Notification As Notification
Dim n As NB6
n.Initialize("default", Application.LabelName, "DEFAULT").AutoCancel(True).SmallIcon(usbmeter)
Dim notify As Notification
notify = n.Build("FNB58 USB Meter", "Collecting data...", "tag1", Main)
notify.notify(4) 'It will be Main (or any other activity) instead of Me if called from a service.
Return notify
End Sub
Sub SaveData(data As String)
LogColor("saving data: " & data, Colors.Red)
Dim tw As TextWriter
tw.Initialize(File.OpenOutput(B4XPages.MainPage.rp.GetSafeDirDefaultExternal("data"), "csvdata"&"_"&B4XPages.MainPage.date&"_"&B4XPages.MainPage.time&".csv", True))
tw.WriteLine(data)
tw.Close
End Sub
This seems to work fine, I tested by putting the app in the background while I was watching TV and I would check periodically by bring the app back to the foreground and checking the graph I placed in my main Screen which shows both Voltage and Current signals, I also tested by browsing other apps while my app was in the background and I noticed the app kept running, I was able to save a csv file with a ton of data and here's what my chart looks like
Thanks to everyone for your suggestions, I will continue to test this, one thing I noticed is that the notification doesn't show up when the service starts, unless I switch
this line here
Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_WHEN_NEEDED
to this
Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_ALWAYS
But if I do this then the app will not run as long and it will crash with this error
java.lang.RuntimeException: android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service com.genesis.fnb58/.logdata
So for now, I am happy with the results, again thanks everyone for your advise and suggestions.
Regards,
Walter