Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A guide to obtain a Forever Service on Android #1080

Closed
busslina opened this issue May 30, 2023 · 3 comments
Closed

A guide to obtain a Forever Service on Android #1080

busslina opened this issue May 30, 2023 · 3 comments

Comments

@busslina
Copy link

busslina commented May 30, 2023

Hello, first of all, congrats about this app.

I want to know if you can provide a brief guide or comment about achieve a forever foreground service like you achieved on this app.
If you have some documentation or links that you used to do it. Or simply the main keys.

I want my forever foreground service to be connected to a server via websocket.

Thank you

https://gist.github.com/varunon9/f2beec0a743c96708eb0ef971a9ff9cd
urbandroid-team/dont-kill-my-app#639

@mendhak
Copy link
Owner

mendhak commented Jun 1, 2023

I think I can point at the various things I've done to keep the app alive, but note that it's not always successful, some manufacturer's implementations are quite aggressive and still manage to kill it. Also in some cases I'm not able to achieve the 'kinda guaranteed' 5 minutes interval in doze mode, despite following the Android guidance.

So main thing is to create a service with a notification, that's the important bit.
https://github.com/mendhak/gpslogger/blob/master/gpslogger/src/main/java/com/mendhak/gpslogger/GpsLoggingService.java#L90-L97

In the onstartcommand of the service, I'm also returning a sticky variable:
https://github.com/mendhak/gpslogger/blob/master/gpslogger/src/main/java/com/mendhak/gpslogger/GpsLoggingService.java#L144 - it's from so long ago I can't remember what this is doing, I think it tells the OS to restart the service in case it's killed.

There's more, in the onDestroy, where the OS might destroy the app while it's running, I've sent a broadcast to the app itself to restart.
https://github.com/mendhak/gpslogger/blob/master/gpslogger/src/main/java/com/mendhak/gpslogger/GpsLoggingService.java#L155-L158

You can see as well, on low memory, an attempt to log the next point after a few minutes have passed, to give the OS some time to rest. https://github.com/mendhak/gpslogger/blob/master/gpslogger/src/main/java/com/mendhak/gpslogger/GpsLoggingService.java#L163-L170

When I set the alarm for the next point I'm using the AlarmManager. Not sure if it's the best approach and I think JobManager is recommended now but I haven't had time to look into it. Anyway the AlarmManager: https://github.com/mendhak/gpslogger/blob/master/gpslogger/src/main/java/com/mendhak/gpslogger/GpsLoggingService.java#L1012

I think that's it, aside from that some attempts at not being too aggressive with battery usage. eg, adding a bit of sleep in the loops. Not trying to use too much memory. No science behind these last bits, it's more superstition than anything else.

@mendhak
Copy link
Owner

mendhak commented Jun 1, 2023

I think you'll have trouble keeping a websocket connection open 'forever'. The service needs to be resilient against pauses and restarts and doze mode, and all their documentation indicates that they want your service to be doze compliant. That is, it gets stopped when the user has turned the phone off, it is allowed to wake up every 5 minutes (or 20) and do some network work, and then go back to sleep. A websocket of course is holding the connection open so you may run into issues.

The most common way I've seen around this is to use Firebase Cloud Messaging, which works even in doze mode.

@busslina
Copy link
Author

busslina commented Jun 1, 2023

Thanks you for your time.

I had my Foreground Notification and it last from 4 to 30 hours depending on the mobile device.
I realised that it is a lost battle to fight against the fact that the service will be killed at some point. I was at this point when I opened this issue.

I cannot use Firebase for my case.

Now, I think that I found the most close way to achieve my goal. Like you said, I use AlarmManager to execute periodically and checks if Foreground Service is still alive. If not, it relaunch it again. For Android +10 (API +29), in order to be allowed to start from background, SYSTEM_ALERT_WINDOW permission is needed to be declared in Android Manifest file and to be requested and granted.

I use an one second periodic interval, but AlarmManager is fired in average every 60 seconds on my mobile device.

I hope this thread helps someone and if anyone has a finest solution it is welcome

@busslina busslina closed this as completed Jun 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants