icecondor background process again

The background process, called Pigeon, in IceCondor is actually kind of a joke. it does not stay running no matter how i coax it. even with android 2's startForeground, it dies like a canary in a coalmine. Pigeon gets killed soon after the app is paused or the phone goes to sleep. What does work is timers. If the background process kicks off a recurring timer, that will stay running quite reliably. Also the callback registration for location change. This continues to fire because the location manager is part of the android system. A system thread, from what i can gather, executes the app's callback.

That also means its a good idea to keep the work done in that callback to a minimum. The callback keeps a pigeon-scope reference to the last receive location (for quick lookup from the app (called Radar)). It has a routine to determine if this fix is a 'valuable' one, then it adds that location in JSON format to a queue. It spins off another thread to push the top of the queue. The callback likes to finish quickly, and yet we want to get a valuable fix to the server ASAP.

typo:code private Location last_recorded_fix, last_local_fix;

public void onLocationChanged(Location location) { last_local_fix = location; long time_since_last_update = last_local_fix.getTime() - (last_recorded_fix == null?0:last_recorded_fix.getTime()); long record_frequency = Long.decode(settings.getString(SETTING_TRANSMISSION_FREQUENCY, "180000")); rssdb.log("pigeon onLocationChanged: lat:"+location.getLatitude()+ " long:"+location.getLongitude() + " acc:"+ location.getAccuracy()+" "+ (time_since_last_update/1000)+" seconds since last update"); if (on_switch) { if((last_local_fix.getAccuracy() < (last_recorded_fix == null? 500000:last_recorded_fix.getAccuracy())) || time_since_last_update > record_frequency ) { last_recorded_fix = last_local_fix; last_fix_http_status = 200; long id = rssdb.addPosition(locationToJson(last_local_fix)); rssdb.log("Pigeon location queued. location #"+id); pushQueue(); } } } /typo:code

A push, with some error handling.

typo:code public void pushQueue() { Timer push_queue_timer_single = new Timer("Push Queue Single Timer"); push_queue_timer_single.schedule(new PushQueueTask(), 0); }

class PushQueueTask extends TimerTask { public void run() { Cursor oldest; rssdb.log("** Starting queue push of size "+rssdb.countPositionQueueRemaining()); if ((oldest = rssdb.oldestUnpushedLocationQueue()).getCount() > 0) { int id = oldest.getInt(oldest.getColumnIndex("_id")); Location fix = locationFromJson( oldest.getString( oldest.getColumnIndex(GeoRss.POSITION_QUEUE_JSON))); int status = pushLocation(fix); if (status == 200) { rssdb.log("queue push #"+id+" OK"); rssdb.mark_as_pushed(id); } else { rssdb.log("queue push #"+id+" FAIL"); } oldest.close(); } rssdb.log("** Finished queue push. size = "+rssdb.countPositionQueueRemaining()); } } /typo:code

There is also a timer that fires every 30 seconds to push out any older queue entries.

typo:code private void startPushQueueTimer() { push_queue_timer = new Timer("PushQueue Timer"); push_queue_timer.scheduleAtFixedRate(new PushQueueTask(), 0, 30000); } /typo:code

This needs to change in that I want a push at the rate of the update frequency, new fix or not. This will give a hearbeat to the server, and can be used to report environmental values which are always changing, starting with the battery level. PushQueueTask needs to be refactored a bit to do this:

  1. build basic json hash
  2. add environmental values
  3. if there is an entry in the queue, add those values too
  4. push