3

I'm implementing an app that listens and takes actions when the user shakes the phone.

So I implemented the following service:

public class ShakeMonitorService extends Service {

    ...
    ShakeDetector shakeDetector;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        shakeDetector= new ShakeDetector(this);
        shakeDetector.start();
        ....
        startForeground(MY_ID, myNotification);
        return Service.START_STICKY;
    }

    ...
}

and start the service in the MainActivity's onCreate

ContextCompat.startForegroundService(this, 
          new Intent(this, ShakeMonitorService.class));

In the shakeDetector I listen the sensor events for the accelerometer as described here.

It works correctly on my devices but some users reports that it works until they lock their devices for long time (i.e. 3hours). From this moment the app stops detecting the shake gestures even when using the device (screen on) until they launch the app again.

What is going on? I supposed Android kills or suspends the app and stops the service until it is opened again.

How can I avoid this?

Important note: I don't want to avoid the system to enter in sleep mode, but I want to recover the execution when the system exits the sleep mode.

Addev
  • 31,819
  • 51
  • 183
  • 302
  • 1
    Use a foreground service with notification, apps in background are subject to pause/killing their process. – Pawel Feb 17 '19 at 19:28
  • Forgot to mention that I'm already starting the ShakeMonitorService in foreground – Addev Feb 17 '19 at 20:49
  • 2
    Does service itself get terminated (notification gets removed) or only detector gets suspended? Is it possible to narrow down devices to specific brands? Some OEM implementations are more aggressive than default, and will force stop even foreground services unless they are explicitly whitelisted in manufacturers battery saver app. – Pawel Feb 17 '19 at 20:54
  • I second what @Pawel is saying. I also have an app that runs a foreground service and I know for certain that both Xiaomi (MIUI) as well as Huawei (EMUI) have their own battery optimizations that interfere with the service without killing it. Users can disable this manually in app settings. Unfortunately I haven't yet found an elegant way to handle this for all manufacturers. – user8118328 Feb 01 '20 at 12:16

2 Answers2

0

i understood that you already started the service as foreground with notification and this will give your service the highest priority. you can easily check if the service is still running or not by checking the notification because the notification will be shown as soon as the service is running. but if the notification is still showing but you notice that the service execution rating is less than you expect(paused and then will run again like round robin). then i think this behavior is caused by the android as an operating system it needs to save the battery as much as possible so the execution of the service will be different when the device is plugged in charger or device is unlocked and on or the device is locked.

but if the notification is becoming dismissed then this mean that the service is killed by some bugs in your code which lead to an exception in your service code or by memory leak and if you already set the service flag to START_STICKY or START_REDELIVER_INTENT the system is starting the service again after a while

Ramy Ibrahim
  • 656
  • 4
  • 19
0

After a lot of research I can say the problem is specific to cusom roms, As I only have MI phone and use MIUI, I don't know If It's present in other CUSTOM ROMs, but I can surely say It's not a problem in stock android. And In MIUI you need to go to Security app -> Battery and Performance -> App Battery saver and manually set your app to "No restrictions"! And there is an easy way to do It with Intent, check this answer!