package org.ohmage.service;
import com.commonsware.cwac.wakeful.WakefulIntentService;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
/**
* A wakeful intent service based on {@link WakefulIntentService} but which
* allows more flexiblity related to when the lock is released.
*
* @see {@link WakefulService#releaseLock() }
* @author cketcham
*/
public abstract class WakefulService extends Service {
abstract protected void doWakefulWork(Intent intent);
static final String NAME="org.ohmage.service.OhmageWakefulIntentService";
private static volatile PowerManager.WakeLock lockStatic=null;
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic==null) {
PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
NAME);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
public static void sendWakefulWork(Context ctxt, Intent i) {
getLock(ctxt.getApplicationContext()).acquire();
ctxt.startService(i);
}
public static void sendWakefulWork(Context ctxt, Class<?> clsService) {
sendWakefulWork(ctxt, new Intent(ctxt, clsService));
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
PowerManager.WakeLock lock=getLock(this.getApplicationContext());
if (!lock.isHeld() || (flags & START_FLAG_REDELIVERY) != 0) {
lock.acquire();
}
super.onStartCommand(intent, flags, startId);
doWakefulWork(intent);
return(START_REDELIVER_INTENT);
}
/**
* Should be called in a try catch block before {@link Service#stopSelf}
*
* <pre>
* try {
* ...code here
* } finally {
* releaseLock();
* stopSelf();
* }
* </pre>
*/
protected void releaseLock() {
PowerManager.WakeLock lock=getLock(this.getApplicationContext());
if (lock.isHeld()) {
lock.release();
}
}
}