Endless foreground service never works as expected - android

I am creating application that has endless ForegroundService for new android versions.
Problem is that ForegroundService always dies after some time no matter what.
Tried to do Battery optimization, Wake lock, creating new process for service, even creating JobScheduler that checks if Service still working, but that one also stops working after some time.
Tried to follow Google samples, Stackoverflow solutions and many others, nothing seems to work.
I also made some research on my banking app and some other apps that relies on services for notifying the user or tracking some activities, they also not working flawlessly like old times.
At the end I figure out that for some Vendor phones doing some extra setting Vendor specific setting helps, this link one of many examples to understand Slack Known issues with Android .
After this reading, I don't think that simple user should go somewhere in to deep phone setting to make app that he likes to work... In fact I think it is the worst practice....
Made some conclusion after researching that because of saving few battery percents Google and poorly made Vendors battery saving strategies on top making phones dump and not reliable....
Also these background restrictions making not possible to develop awesome pocket portable device features...
I mean I agree with ForegroundService idea for long running task instead of simple Service in background that might be malware, spying or whatever that user does know nothing about it. Also agree that User is notified about high power usage, but randomly killing everything is same as killing the idea of smart device.
Please tell me that I am wrong about everything and give me a solution :)

Related

Battery drain via Google Play Services persists after location services are used in Android

I'm using location & activity recognition features of android. Used for realtime location tracking. Currently using the latest ConnectionLess APIs. I have encountered the following problem:
After starting the location, activity services, once in a while, the battery starts to get drained. The behavior is pretty strange as the entire drain is showed under Google Play Services. The drain persists even if the app is stopped, killed, etc. To my surprise, the drain persisted even when the app was uninstalled and it took a couple of full battery re-charges to come out of the situation.
I'm more or less sure that the drain is triggered by my app as multiple devices have recorded the issue and these devices are from different manufacturers and across multiple android OS versions. In ADB shell, I find com.google.android.gms taking up 126% CPU permanently as seen below:
Next, I listed all the threads under that process. Result attached below:
As seen there's one thread, CastSocketMulti running. All other threads are sleeping.Didn't get much on castSocketMulti other than some basic information like it is related to casting in android, etc. We aren't using anything related to casting in our app.
After, killing the process, the drain stops.
Note: I found same question here, however unanswered.
Edit: Every time the battery drain happens, as above, com.google.android.gmsis listed as the number one process taking 100%+ CPU and the castSocketMulti, the only thread of that process in R status
Update: I have opened an issue here.
Pls leave a star so that it may go high on priority
I have found the exact same thing here on a OnePlus 3. I'm not rooted and can't kill the process, but using adb to clear the cache of com.google.android.gms makes the process crash and alleviates the problem for a few days.
Do you use Android Auto or Android Pay? It seems to happen more frequently when I use those two apps in particular.
OK, Google claims to have fixed the issue and they have marked the issue as 'Fixed'. Details here

Does android log somewhere which app was started/running when?

Does android somehow keep track of which apps are/were running and if so when it was in foreground or background, etc?
I already had a look at adb logcat, which gives a rather overwhelming amount of data and I'm not quite sure if I actually will be able to deduce what was started when, but that might be possible.
Seeing how that log disappears after a while and does not survive reboots, I was curious if I'm maybe there might other places where android keeps information about running apps. For instance a colleague mentioned that iOS running apps can usually be deduced from the automatic screenshots it takes for app switching.

Custom-fit Android app: auto-update and always-on?

I'm trying to develop an app that would normally be considered to be malware, but the customer's demands are very specific and logical. We have around 50-100 cheapset Android phones that are bolted down, plugged in, and the app is supposed to send some of the sensor data via tcp to a remote server. It sounds simple enough, but there are two features that I struggle with (since I'm not an experienced Android developer, and have never rooted a phone):
#1 The app should be always on. If it crashes, server should get the error report (stack trace), and the app should be restarted after 10 minutes one more time before giving up. Also, the OS could theoretically kill the app (although I did my best to minimize the memory usage). I'd like to somehow handle that as well.
#2 It would be great if the app could be remotely updated, or auto-updated, with no user interaction whatsoever (since there is no conventional user).
To implement #1, I see no other solution than to root the phone (AlarmsManager doesn't seem to work as I expected, and adding another application to take care of the first one just feels wrong). Is there anything I'm missing?
I don't know how to approach implementing feature #2 at all. If I put the app on the market and check the "keep this application always up to date" checkbox while installing it, will that work? I fear that the auto-update would not occur while the service is running, and even if it did, that the OS would not restart the service after installing the update (unless feature #1 is implemented). If I programatically download the latest .apk and open it, I still need the user to click the "Install" button. I'm even considering implementing the updateable part in some scripting language.
Is there a solution to these problems within the limits of Android API?
EDIT: Thank you all for your answers, you've been very helpful. It seems that the only way to make Android behave as a non-user piece of hardware is to root it. That's the only way to do silent auto-updates. Always on can then be implemented by enabling cron (AlarmManager apparently doesn't fire the event in case of service termination via crash, but it could be used by another trivial, non-crashable service to keep the first one running).
For #1 you can use an foreground service. I don't know how often you need to get sensor data, but what's the problem with AlarmManager? I don't see how rooting could help with #1 though. You can't really do #2 without rooting or building your firmware. If you install your app as a system app (in /system/app) you can use a hidden PackageManager to silently install the new version. Using Market/Play autoupdate should work as well, but you have no way to control the update schedule. And, yes, it won't restart your service, but if you use AlaramManager, this shouldn't be a issue.
All in all, stock Android is not exactly an embedded system that gives you full control, so depending on how much time/effort you are willing to spend, you might want to customize it somewhat (or find a custom ROM that gets close to your requirements).
Re: question #2, there are a few open-source (licensed under the Apache Software License 2.0) options you may check and see how it works.
https://github.com/lazydroid/auto-update-apk-client is the android client for the auto update service (i'm affiliated with), which is small, easy to implement and supports silent updates on rooted devices.
https://github.com/commonsguy/cwac-updater is written by Mark Murphy, however it might require you to run your own update server and I'm not sure about silent updates.

Explicitly Managing WiFi Power Consumption in Android

Background
I'm developing a research application that runs on Android phones. In short, the application runs so long as the phone is on and periodically takes information from many components and sensors on the phone. The application is to disturb the user as little as possible. That being said, it's draining the battery far too quickly and forces the user to recharge every day. This simply won't do.
To try and figure out how to improve the situation, a colleague also working on the application let the application run for a long period of time and noticed that the biggest battery hog is WiFi. My current idea is to manually shut off WiFi when it's not in use in an attempt to save power. AFAIK, Android uses PSM for WiFi to accomplish this to some end, but it doesn't seem to be enough.
Problem
Is there a way to "ramp up" Android's PSM? Or, if there is not as this question suggests, is there any way that I can safely turn WiFi on and off without adversely affecting the user? I.e., is there a way to tell which applications are using WiFi and turn it off when none are? Do standard applications - such as the web browser and email clients - use WiFi locks to prevent WiFi from being turned off when they are working?
Any advice on where to start in solving this problem are greatly appreciated. Information on how Android's PSM works, how long it takes for it to take effect, or any information relevant to the problem are very welcome.
Thanks for your time!
Is there a way to "ramp up" Android's PSM?
Not via the Android SDK.
I.e., is there a way to tell which applications are using WiFi and turn it off when none are?
The OS does this already.
Do standard applications - such as the web browser and email clients - use WiFi locks to prevent WiFi from being turned off when they are working?
Some probably do. You are welcome to search the Android source code and find out. Of course, bear in mind that there are no "standard applications" -- I presume you are thinking of the ones that are part of the Android open source project.
Any advice on where to start in solving this problem are greatly appreciated.
Find out where in your own code you are being inefficient, specifically here:
the application runs so long as the phone is on and periodically takes information from many components and sensors on the phone.
If the device behaves fine when your code is not running, and the device does not behave fine when your code is running, then the problem lies in your code. Conversely, if the device does not behave fine even when your code is not running, then something else is afoot (device defect, firmware defect, rogue application, etc.), but it probably has nothing to do with StackOverflow.

Samsung "App optimisation" feature kills background applications after 3 days

We are currently developing an Android app that is a fitness-tracker application. It runs constantly in the background, and it works fine on most devices, but we've been having issues with the application dying completely on some Samsung devices. After some investigation, it seems like some Samsung devices has a completely custom "App Optimisation" feature (http://forums.androidcentral.com/samsung-galaxy-s6/599408-app-optimisation-after-updating.html), which is basically a (very) primitive version of the Doze feature that exists in later versions of Android which basically just murders apps if they haven't been used for three days.
As this app is more or less only doing logging, and doesn't open the activity, it presents a big problem for us, because this feature is pre-enabled on many Samsung devices. The problem is solved by using a foreground service, but that is a sledgehammer of a solution that requires disturbing the user with a constant notification, and we really don't need the app to be in the foreground - we are fine with the normal power management of Android.
The Samsung App Optimisation feature clearly states that it will "optimise" apps if they have not been used for three days. Does anyone have insight in what Samsung considers to be "used" and can I somehow trigger that?
Side-rant: In my opinion, this is a badly implemented feature that makes development on Android more hostile. Besides our use case, it will any messenger applications break. If it were not for the fact that Facebook Messenger and Whatsapp are hard-wired to be exempt for the app, users would be going crazy because it would be breaking their experiences.
I've owned (and currently own) Samsung devices, so I know a little as to how it works from the user's point of view. The technical specifications and how it works on the inside is an entirely separate issue, and one I can't answer.
The system can detect if you open an app. Samsung uses that in their app optimization, and will save power on apps that haven't been used in over three days. It is a terrible system though.
It ignores background-processes that may be critical to apps, and even if it is an app you actively use, like a fitness tracker, it will have issues. To quote what it says inside the app optimization-list:
"To save battery power, apps that haven't been used for more than 3 days will be designated to save power. Apps designated to save power may not show notifications"
(Rough translation from Norwegian, originally taken from an S6 running Android 6)
Therefore, apps that have been manually, or automatically set (3 days of no use) may give various issues with background processes. But remember that the user can set any app to never save battery, and ignoring the automatic setting. So with this in mind, let's consider possible solutions.
There is one scenario where you do not need to worry about the app and app optimization: When app optimization is disabled entirely.
Looking aside that, there is really only two things you can do:
Ask users on Samsung to disable battery optimization for your app to prevent issues
As #MinaSamy suggested (in their now deleted answer), SyncAdapter and having a periodic synchronization. Note that I haven't tested this, so I don't know whether it works or not.
And there's also a third option, which really isn't a solution, but you can ignore it and gamble on app optimization being disabled, or just not care about it at all.
Does anyone have insight in what Samsung considers to be "used" and can I somehow trigger that?
As far as I know, unless Samsung added some safeguards against accidental opening or added some kind of minimum activity requirement, opening is enough. It appears to be a "stupid" feature, which runs on hard-coded rules rather than a dynamic system that actually detects app use and sets power saving relative to that. It's "easy to enable", but fortunately easy to disable as well.
Meaning you cannot trigger an event that will keep it alive (unless SyncAdapter does the trick)
And to make the facts clear, from #Neil's answer:
It does seem like the user can do this, so there must be some database or setting somewhere that controls it.
There kinda is. There are a total of four settings, three of which are app-specific, and it is stored in a database (or some other form of data storage). These four settings can be used, although extremely shallow, to alter the behavior of the app optimization:
Always optimize
Automatic optimization
Never optimize
Disable app optimization
The first three options are on a per-app basis, which means each app can have separate settings. Disabling app optimization is exactly what you'd expect: it disables the entire feature for all apps. If it's disabled entirely, nothing is optimized.
There's also a website listing ways of bypassing optimizations on a per-brand basis. The entry for Samsung is more or less what I've said: tell the user to manually disable optimization. There are no developer solutions.
In settings>device health>battery there's an option to "put unused apps to sleep". You can turn it off, or change the amount of time it takes, which is 3 days by default.
Sounds like that's your problem.
https://forums.androidcentral.com/samsung-galaxy-s10-s10-plus/964083-whats-disabling-some-my-apps-background.html
Is there a reason you can't add your service to the 'don't optimise' list?
It does seem like the user can do this, so there must be some database or setting somewhere that controls it.
Alternatively, if you detect you are installing on one of the devices, open the optimise activity page, and show a message saying "Don't optimise us!".
As a workaround, i implemented the SyncAdapter mechanism, using this link as a good starting point: https://github.com/bmeike/MiniSync
It doesn't work perfectly (for testing, in my app i write a log every 1h, and after 3 days, it starts not respecting this scheduling), but at least it doesn't stop after 3 days, without the need to put the app in ignored optimization mode.
UPDATE: After the update to android PIE, scheduling stopped again after 3 days.
On another device, same app with android Oreo, scheduling is working (even if not completely respected).
On Samsung phones, the culprit is this Sleep setting:
You have got to take your users to this system settings screen and ask them to turn the feature off.
In my opinion you should implement a 'Broadcast Receiver' that listens to a custom 'Intent' and this 'Intent' to be Broadcasted by the 'Service' from 'onDestroy()' method of the 'Service' because when the 'System' kill the 'Service' this method will be called definitely.
And when the 'Broadcast Receiver' receives the 'Intent' you should start the 'Service' again.
And to distinguish between you stopping the 'Service' or the 'System' stopping the 'Service' just use some 'booleans' stored in 'SharedPreferences' and then in the 'Broadcast Receiver' you decide whether to activate the 'Service' or not
we are fine with the normal power management of Android
Are you? From the Android docs
However, since the user is not directly aware of a background service, in that state it is considered a valid candidate to kill, and you should be prepared for this to happen. In particular, long-running services will be increasingly likely to kill and are guaranteed to be killed (and restarted if appropriate) if they remain started long enough.
Three days seems like it would fall under "long-running...guaranteed to be killed".
If the problem is not that your service is killed but that it isn't restarted, you could use the AlarmManager to regularly check the status of your service and restart, if necessary.

Categories

Resources