• 8
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

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:

  1. Ask users on Samsung to disable battery optimization for your app to prevent issues

  2. 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.

  • 8
Reply Report
      • 1
    • Thanks for the response. I have a similar issue where a Broadcast receiver registered in manifest (for bluetooth connection events), seems to malfunction after 3 days (not receiving all events). Will adding my app to "Unmonitored apps" list in Samsung battery settings solve this? Is this the only solution? Thanks!
      • 2
    • @dor506 assuming it's a Samsung-only issue, yes. If you're seeing it on other devices, it's likely there's a problem with your code (assuming the device doesn't have something similar to Samsungs "feature", looking aside Doze)
      • 2
    • Thanks for the quick response. I'm pretty sure it is not an issue in my code, as the only thing I do is write the events to a log file. The log shows that the events are getting received fine for ~3 days. after this period, according to the log, the events not always getting received - Which seems to be related to the Samsung 3-day described here. It seems that after this period, the the receiver priority is getting downgraded

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!".

  • 1
Reply Report
      • 1
    • "It does seem like the user can do this, so there must be some database or setting somewhere that controls it." That is an idea, but what database would that be? How could I find that out?
      • 2
    • The first thing I would do, is dig around on the file system of one of the affected phones. There might be something as simple as a comma separated list of apps that are optimised (probably not, but you never know).

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

  • -1
Reply Report

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).

  • -1
Reply Report

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.

  • -3
Reply Report
    • I'm well aware of how the stock Android power management works, and that services are randomly killed and restarted. That is fine. We have many non-Samsung devices with the same version number of android running just fine for many days. But what the Samsung App Optimiser does is different - after three days exactly, it completely kills the entire app. Permanently. It never restarts any of it. It cannot even receive GCM messages, or receives package updated events. It is NOT the same as the stock Android power management.
    • No, they do not. The application is completely shut down (force quit button disabled in Android settings), and nothing seems will make it come up again except actually pressing the app icon again.