Commit 569a6e81 authored by Chris Scott's avatar Chris Scott

Keep a single stationaryRegion PendingIntent instance rather than re-creating...

Keep a single stationaryRegion PendingIntent instance rather than re-creating it each time we need to addProximityAlert.  This seems to have improved lock-ups coming out of a stationary-region.  Minor cleanup, re-arrange some lines, add docs
parent 1c6b5055
...@@ -64,7 +64,7 @@ public class LocationUpdateService extends Service implements LocationListener { ...@@ -64,7 +64,7 @@ public class LocationUpdateService extends Service implements LocationListener {
private float stationaryRadius; private float stationaryRadius;
private Location stationaryLocation; private Location stationaryLocation;
private PendingIntent stationaryAlarmPI; private PendingIntent stationaryAlarmPI;
private PendingIntent proximityPI; private PendingIntent stationaryRegionPI;
private PendingIntent singleUpdatePI; private PendingIntent singleUpdatePI;
private Boolean isMoving = false; private Boolean isMoving = false;
...@@ -99,27 +99,29 @@ public class LocationUpdateService extends Service implements LocationListener { ...@@ -99,27 +99,29 @@ public class LocationUpdateService extends Service implements LocationListener {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
Log.i(TAG, "OnCreate"); Log.i(TAG, "OnCreate");
locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
toneGenerator = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
// Stationary region PendingIntent locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
stationaryAlarmPI = PendingIntent.getBroadcast(this, 0, new Intent(STATIONARY_ALARM_ACTION), 0); alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
toneGenerator = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
// Stop-detection PI
stationaryAlarmPI = PendingIntent.getBroadcast(this, 0, new Intent(STATIONARY_ALARM_ACTION), 0);
registerReceiver(stationaryAlarmReceiver, new IntentFilter(STATIONARY_ALARM_ACTION)); registerReceiver(stationaryAlarmReceiver, new IntentFilter(STATIONARY_ALARM_ACTION));
// Stationary region PI
stationaryRegionPI = PendingIntent.getBroadcast(this, 0, new Intent(STATIONARY_REGION_ACTION), PendingIntent.FLAG_CANCEL_CURRENT);
registerReceiver(stationaryRegionReceiver, new IntentFilter(STATIONARY_REGION_ACTION)); registerReceiver(stationaryRegionReceiver, new IntentFilter(STATIONARY_REGION_ACTION));
// Construct the Pending Intent that will be broadcast by the oneshot // One-shot PI (TODO currently unused)
// location update.
singleUpdatePI = PendingIntent.getBroadcast(this, 0, new Intent(SINGLE_LOCATION_UPDATE_ACTION), PendingIntent.FLAG_UPDATE_CURRENT); singleUpdatePI = PendingIntent.getBroadcast(this, 0, new Intent(SINGLE_LOCATION_UPDATE_ACTION), PendingIntent.FLAG_UPDATE_CURRENT);
registerReceiver(singleUpdateReceiver, new IntentFilter(SINGLE_LOCATION_UPDATE_ACTION)); registerReceiver(singleUpdateReceiver, new IntentFilter(SINGLE_LOCATION_UPDATE_ACTION));
connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
wakeLock.acquire(); wakeLock.acquire();
// Location criteria
criteria = new Criteria(); criteria = new Criteria();
criteria.setAltitudeRequired(false); criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false); criteria.setBearingRequired(false);
...@@ -150,28 +152,30 @@ public class LocationUpdateService extends Service implements LocationListener { ...@@ -150,28 +152,30 @@ public class LocationUpdateService extends Service implements LocationListener {
this.setPace(false); this.setPace(false);
} }
/** /**
* Experimental cell-location-change handler * Experimental cell-location-change handler. Hoping to implement something like ios Significant Changes system
* *
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(phoneStateListener, LISTEN_CELL_LOCATION); telephonyManager.listen(phoneStateListener, LISTEN_CELL_LOCATION);
* *
*/ */
//We want this service to continue running until it is explicitly //We want this service to continue running until it is explicitly stopped
// stopped, so return sticky.
return START_STICKY; return START_STICKY;
} }
@Override @Override
public boolean stopService(Intent intent) { public boolean stopService(Intent intent) {
Log.i(TAG, "Received stop: " + intent); Log.i(TAG, "- Received stop: " + intent);
cleanUp(); cleanUp();
Toast.makeText(this, "Background location tracking stopped", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "Background location tracking stopped", Toast.LENGTH_SHORT).show();
return super.stopService(intent); return super.stopService(intent);
} }
/**
*
* @param value set true to engage "aggressive", battery-consuming tracking, false for stationary-region tracking
*/
private void setPace(Boolean value) { private void setPace(Boolean value) {
Log.i(TAG, "setPace: " + value); Log.i(TAG, "setPace: " + value);
...@@ -288,18 +292,21 @@ public class LocationUpdateService extends Service implements LocationListener { ...@@ -288,18 +292,21 @@ public class LocationUpdateService extends Service implements LocationListener {
stationaryLocation = location; stationaryLocation = location;
} }
if (stationaryLocationAttempts++ == MAX_STATIONARY_ACQUISITION_ATTEMPTS || (stationaryLocation.getAccuracy() <= stationaryRadius) ) { if (stationaryLocationAttempts++ == MAX_STATIONARY_ACQUISITION_ATTEMPTS || (stationaryLocation.getAccuracy() <= stationaryRadius) ) {
isAcquiringStationaryLocation = false;
startMonitoringStationaryRegion(stationaryLocation); startMonitoringStationaryRegion(stationaryLocation);
} else { } else {
// Unacceptable stationary-location: bail-out and wait for another.
return; return;
} }
} else if (isAcquiringSpeed) { } else if (isAcquiringSpeed) {
// Make *tick* sound, acquiring speed. // Make *hoo* sound, acquiring speed.
if (isDebugging) { if (isDebugging) {
toneGenerator.startTone(ToneGenerator.TONE_SUP_RADIO_ACK); toneGenerator.startTone(ToneGenerator.TONE_SUP_RADIO_ACK);
} }
if (speedAcquisitionAttempts++ == MAX_SPEED_ACQUISITION_ATTEMPTS) { if (speedAcquisitionAttempts++ == MAX_SPEED_ACQUISITION_ATTEMPTS) {
// Got enough samples, assume we're confident in reported speed now. Play "woohoo" sound. // Got enough samples, assume we're confident in reported speed now. Play "woohoo" sound.
if (isDebugging) { if (isDebugging) {
// @sound doodly-doo
toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE); toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE);
} }
isAcquiringSpeed = false; isAcquiringSpeed = false;
...@@ -321,6 +328,7 @@ public class LocationUpdateService extends Service implements LocationListener { ...@@ -321,6 +328,7 @@ public class LocationUpdateService extends Service implements LocationListener {
setPace(true); setPace(true);
} }
} }
// Go ahead and cache, push to server
lastLocation = location; lastLocation = location;
persistLocation(location); persistLocation(location);
...@@ -349,27 +357,22 @@ public class LocationUpdateService extends Service implements LocationListener { ...@@ -349,27 +357,22 @@ public class LocationUpdateService extends Service implements LocationListener {
private void startMonitoringStationaryRegion(Location location) { private void startMonitoringStationaryRegion(Location location) {
Log.i(TAG, "- startMonitoringStationaryRegion (" + location.getLatitude() + "," + location.getLongitude() + "), accuracy:" + location.getAccuracy()); Log.i(TAG, "- startMonitoringStationaryRegion (" + location.getLatitude() + "," + location.getLongitude() + "), accuracy:" + location.getAccuracy());
if (isDebugging) { if (isDebugging) {
// @sound "beeeeeeeeeeeeeeeeep"
toneGenerator.startTone(ToneGenerator.TONE_CDMA_ABBR_ALERT); toneGenerator.startTone(ToneGenerator.TONE_CDMA_ABBR_ALERT);
} }
stationaryLocation = location; stationaryLocation = location;
isAcquiringStationaryLocation = false;
locationManager.removeUpdates(this); locationManager.removeUpdates(this);
// Sanity check: ensure removed previous proximity-detector // Remove previous stationaryRegionPI just in case.
if (proximityPI != null) { locationManager.removeProximityAlert(stationaryRegionPI);
locationManager.removeProximityAlert(proximityPI);
proximityPI = null;
}
Intent intent = new Intent(STATIONARY_REGION_ACTION);
proximityPI = PendingIntent.getBroadcast(this, 0, intent, 0);
// Here be the execution of the stationary region monitor
locationManager.addProximityAlert( locationManager.addProximityAlert(
location.getLatitude(), location.getLatitude(),
location.getLongitude(), location.getLongitude(),
(location.getAccuracy() < stationaryRadius) ? stationaryRadius : location.getAccuracy(), (location.getAccuracy() < stationaryRadius) ? stationaryRadius : location.getAccuracy(),
-1, -1,
proximityPI stationaryRegionPI
); );
} }
...@@ -380,27 +383,25 @@ public class LocationUpdateService extends Service implements LocationListener { ...@@ -380,27 +383,25 @@ public class LocationUpdateService extends Service implements LocationListener {
if (isDebugging) { if (isDebugging) {
new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100).startTone(ToneGenerator.TONE_CDMA_CONFIRM); new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100).startTone(ToneGenerator.TONE_CDMA_CONFIRM);
} }
// Destroy the stationary-region detector that caused this event to be caught.
if (proximityPI != null) {
Log.i(TAG, "- proximityPI: " + proximityPI.toString());
locationManager.removeProximityAlert(proximityPI);
proximityPI = null;
}
// There MUST be a valid, recent location if this event-handler was called. // There MUST be a valid, recent location if this event-handler was called.
Location location = getLastBestLocation((int) stationaryRadius, locationTimeout * 1000); Location location = getLastBestLocation((int) stationaryRadius, locationTimeout * 1000);
if (location != null) { if (location != null) {
// Filter-out spurious region-exits. // Filter-out spurious region-exits: must have at least a little speed to move out of stationary-region.
if (location.getSpeed() < 0.75) { if (location.getSpeed() < 0.75) {
return; return;
} }
} else { } else {
Log.i(TAG, "- exit stationary region receiver was triggered but could not fetch the last-best location!"); Log.i(TAG, "- exit stationary region receiver was triggered but could not fetch the last-best location!");
} }
// Kill the current region-monitor we just walked out of.
locationManager.removeProximityAlert(stationaryRegionPI);
// Engage aggressive tracking.
this.setPace(true); this.setPace(true);
} }
/** /**
* TODO Experimental cell-tower change system * TODO Experimental cell-tower change system; something like ios significant changes.
*/ */
public void onCellLocationChanged(CellLocation cellLocation) { public void onCellLocationChanged(CellLocation cellLocation) {
Log.i(TAG, "- onCellLocationChanged"); Log.i(TAG, "- onCellLocationChanged");
...@@ -563,12 +564,7 @@ public class LocationUpdateService extends Service implements LocationListener { ...@@ -563,12 +564,7 @@ public class LocationUpdateService extends Service implements LocationListener {
} }
private void cleanUp() { private void cleanUp() {
locationManager.removeUpdates(this); locationManager.removeUpdates(this);
locationManager.removeProximityAlert(stationaryRegionPI);
// Stationary-region proximity-detector.
if (proximityPI != null) {
locationManager.removeProximityAlert(proximityPI);
proximityPI = null;
}
alarmManager.cancel(stationaryAlarmPI); alarmManager.cancel(stationaryAlarmPI);
unregisterReceiver(stationaryAlarmReceiver); unregisterReceiver(stationaryAlarmReceiver);
unregisterReceiver(stationaryRegionReceiver); unregisterReceiver(stationaryRegionReceiver);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment