Search code examples
javaandroidservicewakelock

android service logging sensor data uninterrupted


I'm trying to write a service for an android app that monitors at a fixed sampling rate continuously the accelerometer sensor values. Below is a snippet of the code that I'm using to keep the service running.

public class MyService extends Service {
    ...
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        Intent mainIntent = new Intent(this, MainActivity.class);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(MainActivity.class);
        stackBuilder.addNextIntent(mainIntent);
        PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        Notification notification = new Notification.Builder(this)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(getString(R.string.app_name))
            .setAutoCancel(true)
            .setOngoing(true)
            .setContentIntent(pendingIntent)
            .setContentText(TAG)
            .build();
        context.startForeground(1, notification);
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag");
        wakeLock.acquire();
        //Register Accelerometer Sensor Listener Here
        return START_STICKY;
}

When the device is running on batteries after some minutes it goes to sleep. The service will be restarted sporadically, but with no consistency. The ideas that I'm considering right now are:

But I wish it wasn't necessary. Does anyone know a way to achieve this sensor logging feature to run always?

--

I also tried changing the sensor listener for a plain repeating thread in case it was only the sensor the one going to sleep, but the effect was the same. I believe it's only related to power management of android

I'm aware of the energy efficiency implications of this, but it is necessary for this application to guarantee that the logging is uninterrupted and at high sampling rate.

EDITED: Changed title to clarify

UPDATE: Converting it to a persistent system application doesn't help


Solution

  • I was able to solve this. Actually it was an error in the code. The WakeLock in the snippet I posted is a local variable and gets garbage collected when the function returns, so there wasn't actually a lock. I fixed it by changing this:

    public class MyService extends Service {
        private PowerManager powerManager;
        private static PowerManager.WakeLock wakeLock;
        ...
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            ...
            powerManager = (PowerManager) getSystemService(POWER_SERVICE);
            wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag");
            wakeLock.acquire();
            ...
    }