Search code examples
androidandroid-serviceandroid-sensors

onSensorChanged not working after sleep for ~5 minutes until app is opened.


I'm facing some strange issue. I have a service which receives sensor updates. Everything works fine until screen turns off for a while. After that onSensorChanged is not called until I open the app from launcher.

Here is my service class:

public class MyService extends Service implements OrientationMonitor.Listener, ScreenReceiver.ScreenStateListener {

    private final OrientationMonitor orientationMonitor = new OrientationMonitor(this);
    private final ScreenReceiver screenReceiver = new ScreenReceiver(this);

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        orientationMonitor.start();
        screenReceiver.register();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        orientationMonitor.stop();
        screenReceiver.unregister();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void screenStateChanged(boolean isScreenOn) {
        if (isScreenOn) {
            orientationMonitor.start();
        } else {
            orientationMonitor.stop();
        }
    }
}

Here is the code of OrientationMonitor:

public class OrientationMonitor implements SensorEventListener {
    private final Listener listener;
    private final WindowManager windowManager;
    private final SensorManager sensorManager;
    private final Sensor rotationSensor;

    public OrientationMonitor(@NonNull Listener listener) {
        this.listener = listener;
        windowManager = (WindowManager) AppContext.get().getSystemService(Context.WINDOW_SERVICE);
        sensorManager = (SensorManager) AppContext.get().getSystemService(Context.SENSOR_SERVICE);
        rotationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
    }

    public void start() {
        if (rotationSensor != null)
            sensorManager.registerListener(this, rotationSensor, 10_000);
    }


    public void stop() {
        if (rotationSensor != null)
            sensorManager.unregisterListener(this, rotationSensor);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        //Here some work is performed
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    public interface Listener {
        void onOrientationChanged(int angle);
    }
}

During the work, when app is minimized and when screen is turned off service receives notification and stops (unregisters) rotation sensor. When screen becomes turned on it registers it again. If I turn off the screen for some time, not bigger than 1-2 mins, then everything is fine, onSensorChanged fires normally.

But when I turn screen of for 5 mins or more the onSensorChanged doesn't fire until I open the app, then it fires immediately without any calls. However, during the debug process I see that sensorManager.registerListener(this, rotationSensor, 10_000); is called when screen turns on.

I found a lot of questions about onSensorChanged not working during the sleep, but it is a little different case.

Already tried partitial wake locks and registering listener from another thread but it didn't help.

Did anyone have the similar situation? Looking forward for your advises and thank you in advance.


Solution

  • I didn't find the reason of this issue, but found a solution. As I said

    when I turn screen of for 5 mins or more the onSensorChanged doesn't fire until I open the app, then it fires immediately without any calls

    So, I created an empty activity with no UI, and I call it immediately after wakeup and finish it in onCreate. This way I was able to make onSensorChanged start working in my service.