androidandroid-service

Android: service for gps / sensor logging


I m looking for the best practice to implement a service for logging gps- or other sensor-values periodically (every 10-60 sec). The service should deal with the standby mode, when the phone goes asleep.

Any help, even pseudo-code, is very much appreciated!


Solution

  • It looks like it is impossible to let the orientation sensors work constantly for hours even though the device may fall asleep (refer to http://code.google.com/p/android/issues/detail?id=3708#makechanges

    As soon as the display goes off, the sensors will do alike... :(

    I now implemented a wakelock (needs permission)

    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    

    in conjunction with a timer and a broadcastreciever that will turn the display back on again. This is of course crazy for battery life but I found no other way so far.

    This is my onCreate method in the service:

    @Override
    public void onCreate() {
    mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    CONTEXT = this;
    PowerManager pm = (PowerManager) CONTEXT.getSystemService(Context.POWER_SERVICE);
    this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "my tag");
    mWakeLock.acquire();
    Log.d(TAG, "Wakelock acquired");
    // register receiver that handles screen on and screen off logic
                IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
                filter.addAction(Intent.ACTION_SCREEN_OFF);
                BroadcastReceiver mReceiver = new ScreenReceiver();
                registerReceiver(mReceiver, filter);
    }
    

    this the onStart method of the service:

    @Override
    public void onStart(Intent intent, int startid) {
    Toast.makeText(this, "My Service Started", Toast.LENGTH_SHORT).show();
    Log.d(TAG, "onStart");
    boolean screenOn = intent.getBooleanExtra("screen_state", false);
                if (!screenOn) {
                    Log.d(TAG, "Screen is on");
                } else {
                 Log.d(TAG, "Screen is off");
             Timer timer = new Timer("DigitalClock");
         timer.schedule(new TimerTask() {
            @Override
            public void run() {
             Log.d(TAG,"Waiting 1 sec for switching the screen back on again...");
         PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
             "my tag");
         mWakeLock.acquire();
            }
         }, 1000);
                 mWakeLock.acquire();
                    }
    }
    

    and this is the BroadcastReceiver class:

    public class ScreenReceiver extends BroadcastReceiver {
         private boolean screenOff;
         @Override
         public void onReceive(Context context, Intent intent) {
                 if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                         screenOff = true;
                 } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
                         screenOff = false;
                 }
                 Intent i = new Intent(context, MyService.class);
                 i.putExtra("screen_state", screenOff);
                 context.startService(i);
         }
    

    }

    This workaround will also do with a device UN-plugged from the debugger via USB (I first had an issue with this).

    Please let me know if you have a better solution, or if there is fix in 2.3. Thanx!