Doing asynchronous work in WakefulIntentService. doWakefulWork() ?

265 views
Skip to first unread message

Mark

unread,
Feb 22, 2010, 1:21:30 PM2/22/10
to cw-android
Hi,

In the advanced android book, Chapter 13: Using System Services - Mark
gives us a template for using the alarm manager. In the end, we can do
our work here:

public class AppService extends WakefulIntentService {
@Override
protected void doWakefulWork(Intent intent) {
.. do your work here ..
}
}

in my case, I'd like to set an alarm for every 20 minutes to see if
the user's geo location has changed by 1000 meters or so. I can do
something like this:

LocationManager mgr =
(LocationManager)getSystemService(LOCATION_SERVICE);
Location locationGps =
mgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location locationWifi =
mgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

but this depends on some other app having run the gps service to
update the last location. It seems like doWakefulWork() should only
contain serial calls and should exit quickly so as to not keep the
user's phone awake for too long.

Is there any clever way of at least checking for network updates
asynchronously within the window of doWakefulWork()? I'd have to
register a location listener, which will be called back after
doWakefulWork() has exited already - not sure if that's legitimate ?

Thanks

Mark Murphy

unread,
Feb 22, 2010, 1:26:59 PM2/22/10
to cw-an...@googlegroups.com

Yeah, that's not going to work.

You would need to use a regular Service, not an IntentService, which
wants to automatically shut down. You would need to manage the WakeLocks
then to keep the CPU alive until you got a location (or until some
timeout, indicating that you're not going to ever get one). Then, at
that point, you could unregister your listener, have the Service
stopSelf() (like the IntentService does), and release the WakeLock.

I poked around at this for a bit late last year, got frustrated, and
moved on to other projects. It's something that definitely could use a
reusable pattern.

--
Mark Murphy (a Commons Guy)
http://commonsware.com | http://twitter.com/commonsguy

_The Busy Coder's Guide to *Advanced* Android Development_
Version 1.3 Available!

Mark

unread,
Feb 22, 2010, 4:32:34 PM2/22/10
to cw-android
Hi Mark,

Ok I think I follow - so it looks like I just have to extend Service
instead of IntentService, and everything else stays pretty similar?:

// All the same here, still acquire lock in onReceive?
public class ReceiverOnAlarm extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
ServiceWakeful.acquireStaticLock(context);
context.startService(new Intent(context, ServiceGeo.class));
}
}

// Now extends Service. Lock should already be obtained by the
// time the service starts. Release it in onDestroy()?
abstract public class ServiceWakeful extends Service
{
public static void acquireStaticLock(Context context); // same
synchronized private static PowerManager.WakeLock getLock(Context
context); // same

@Override
public void onCreate() {
super.onCreate();

// Do any work you want, even spawn another thread,
// then call stopSelf() to release the lock in
// onDestroy()?
stopSelf();
}

@Override
public void onDestroy() {
super.onDestroy();
getLock(this).release();
}
}

Thank you

> Mark Murphy (a Commons Guy)http://commonsware.com|http://twitter.com/commonsguy

Reply all
Reply to author
Forward
0 new messages