Address Rodrigo's comments.

Add service preference manager.
This commit is contained in:
Sandor Dornbush
2010-08-18 22:05:01 -07:00
parent beddc8e1ea
commit 1de9b73aa0
4 changed files with 239 additions and 175 deletions
@@ -1240,7 +1240,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
* Starts the track recording service (if not already running) and binds to
* it. Starts recording a new track.
*/
protected void startRecording() {
public void startRecording() {
if (trackRecordingService == null) {
startNewTrackRequested = true;
Intent startIntent = new Intent(this, TrackRecordingService.class);
@@ -1266,7 +1266,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
* Stops the track recording service and unbinds from it. Will display a toast
* "Stopped recording" and pop up the Track Details activity.
*/
protected void stopRecording() {
public void stopRecording() {
if (trackRecordingService != null) {
try {
trackRecordingService.endCurrentTrack();
@@ -1325,7 +1325,7 @@ public class MyTracks extends TabActivity implements OnTouchListener,
*
* @param trackId the id of the track
*/
protected void setSelectedTrack(final long trackId) {
public void setSelectedTrack(final long trackId) {
runOnUiThread(new Runnable() {
public void run() {
SharedPreferences prefs =
@@ -152,41 +152,7 @@ public class MyTracksMap extends MapActivity
if (selectedTrack == null) {
return;
}
Cursor cursor = null;
try {
cursor = providerUtils.getLocationsCursor(
recordingTrackId,
lastSeenLocationId + 1,
MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS
- selectedTrack.getLocations().size(),
true);
if (cursor != null) {
if (cursor.moveToLast()) {
final int idColumnIdx =
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
int i = 0;
setSamplingFrequency(selectedTrack);
do {
Location location = providerUtils.createLocation(cursor);
if (i % samplingFrequency == 0 ||
MyTracksUtils.isValidLocation(location)) {
lastSeenLocationId = cursor.getLong(idColumnIdx);
if (location != null) {
mapOverlay.addLocation(location);
}
}
i++;
} while (cursor.moveToPrevious());
}
}
} catch (RuntimeException e) {
Log.w(MyTracksConstants.TAG, "Caught an unexpected exception: ", e);
} finally {
if (cursor != null) {
cursor.close();
}
mapView.postInvalidate();
}
readAllNewTrackPoints();
}
};
@@ -199,53 +165,9 @@ public class MyTracksMap extends MapActivity
if (selectedTrack == null) {
return;
}
Cursor cursor = null;
long totalLocations = selectedTrack.getStopId() -
selectedTrack.getStartId();
mapOverlay.clearPoints();
lastSeenLocationId = selectedTrack.getStartId();
setSamplingFrequency(selectedTrack);
int bufferSize = 1024;
try {
int points = 0;
while (lastSeenLocationId < selectedTrack.getStopId()) {
cursor = providerUtils.getLocationsCursor(
selectedTrack.getId(), lastSeenLocationId, bufferSize, false);
if (cursor != null && cursor.moveToFirst()) {
final int idColumnIdx =
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
while (cursor.moveToNext()) {
points++;
Location location = providerUtils.createLocation(cursor);
if (MyTracksUtils.isValidLocation(location)) {
lastSeenLocationId = cursor.getLong(idColumnIdx);
// Include a point if it fits one of the following criteria:
// - Has the mod for the sampling frequency.
// - Is the first point.
// - Is the last point and we are not recording this track.
if (points % samplingFrequency == 0 ||
points == 0 ||
(recordingTrackId != selectedTrack.getId() &&
points == (totalLocations - 1))) {
mapOverlay.addLocation(location);
}
}
}
} else {
lastSeenLocationId += bufferSize;
}
cursor.close();
cursor = null;
}
} catch (RuntimeException e) {
Log.w(MyTracksConstants.TAG, "Caught unexpected exception.", e);
} finally {
if (cursor != null) {
cursor.close();
}
}
mapView.postInvalidate();
readAllNewTrackPoints();
}
};
@@ -1049,4 +971,48 @@ public class MyTracksMap extends MapActivity
Log.i(MyTracksConstants.TAG, "Sampling locations: " + samplingFrequency);
}
private void readAllNewTrackPoints() {
Cursor cursor = null;
// Refetch the track to get the latest StopId
selectedTrack = providerUtils.getTrack(selectedTrack.getId());
long totalLocations = selectedTrack.getStopId() -
selectedTrack.getStartId();
setSamplingFrequency(selectedTrack);
int bufferSize = 1024;
int points = 0;
while (lastSeenLocationId < selectedTrack.getStopId()) {
cursor = providerUtils.getLocationsCursor(
selectedTrack.getId(), lastSeenLocationId, bufferSize, false);
if (cursor != null && cursor.moveToFirst()) {
final int idColumnIdx = cursor.getColumnIndexOrThrow(
TrackPointsColumns._ID);
while (cursor.moveToNext()) {
points++;
Location location = providerUtils.createLocation(cursor);
lastSeenLocationId = cursor.getLong(idColumnIdx);
// Include a point if it fits one of the following criteria:
// - Has the mod for the sampling frequency.
// - Is the first point.
// - Is the last point and we are not recording this track.
if (!MyTracksUtils.isValidLocation(location) ||
points % samplingFrequency == 0 ||
points == 0 ||
(recordingTrackId != selectedTrack.getId() &&
points == (totalLocations - 1))) {
mapOverlay.addLocation(location);
}
}
} else {
lastSeenLocationId += bufferSize;
}
cursor.close();
cursor = null;
}
if (cursor != null) {
cursor.close();
}
mapView.postInvalidate();
}
}
@@ -0,0 +1,122 @@
package com.google.android.apps.mytracks.services;
import android.content.SharedPreferences;
import android.util.Log;
import com.google.android.apps.mytracks.MyTracksConstants;
import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.maps.mytracks.R;
public class PreferenceManager {
private TrackRecordingService service;
private String announcement_frequency_key;
private String max_recording_distance_key;
private String metric_units_key;
private String min_recording_distance_key;
private String min_recording_interval_key;
private String min_required_accuracy_key;
private String signal_sampling_frequency_key;
private String split_frequency_key;
public PreferenceManager(TrackRecordingService service) {
this.service = service;
announcement_frequency_key =
service.getString(R.string.announcement_frequency_key);
max_recording_distance_key =
service.getString(R.string.max_recording_distance_key);
metric_units_key =
service.getString(R.string.metric_units_key);
min_recording_distance_key =
service.getString(R.string.min_recording_distance_key);
min_recording_interval_key =
service.getString(R.string.min_recording_interval_key);
min_required_accuracy_key =
service.getString(R.string.min_required_accuracy_key);
split_frequency_key =
service.getString(R.string.split_frequency_key);
signal_sampling_frequency_key =
service.getString(R.string.signal_sampling_frequency_key);
}
/**
* Notifies that preferences have changed.
* Call this with key == null to update all preferences in one call.
*
* @param key the key that changed (may be null to update all preferences)
*/
public void onSharedPreferenceChanged(String key) {
SharedPreferences sharedPreferences =
service.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (sharedPreferences == null) {
Log.w(MyTracksConstants.TAG,
"TrackRecordingService: Couldn't get shared preferences.");
return;
}
if (key == null || key.equals(min_recording_distance_key)) {
service.setMinRecordingDistance(
sharedPreferences.getInt(
min_recording_distance_key,
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE));
Log.d(MyTracksConstants.TAG,
"TrackRecordingService: minRecordingDistance = "
+ service.getMinRecordingDistance());
}
if (key == null || key.equals(max_recording_distance_key)) {
service.setMaxRecordingDistance(
sharedPreferences.getInt(
max_recording_distance_key,
MyTracksSettings.DEFAULT_MAX_RECORDING_DISTANCE));
}
if (key == null || key.equals(min_recording_interval_key)) {
int minRecordingInterval = sharedPreferences.getInt(
min_recording_interval_key,
MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL);
switch (minRecordingInterval) {
case -2:
// Battery Miser
// min: 30 seconds
// max: 5 minutes
// minDist: 5 meters Choose battery life over moving time accuracy.
service.setLocationListenerPolicy(
new AdaptiveLocationListenerPolicy(30000, 300000, 5));
break;
case -1:
// High Accuracy
// min: 1 second
// max: 30 seconds
// minDist: 0 meters get all updates to properly measure moving time.
service.setLocationListenerPolicy(
new AdaptiveLocationListenerPolicy(1000, 30000, 0));
break;
default:
service.setLocationListenerPolicy(
new AbsoluteLocationListenerPolicy(minRecordingInterval * 1000));
}
}
if (key == null || key.equals(min_required_accuracy_key)) {
service.setMinRequiredAccuracy(
sharedPreferences.getInt(
min_required_accuracy_key,
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY));
}
if (key == null || key.equals(announcement_frequency_key)) {
service.setAnnouncementFrequency(
sharedPreferences.getInt(announcement_frequency_key,
-1));
}
if (key == null || key.equals(split_frequency_key)) {
service.getSplitManager().setSplitFrequency(
sharedPreferences.getInt(split_frequency_key, 0));
}
if (key == null || key.equals(signal_sampling_frequency_key)) {
service.getSignalManager().setFrequency(
sharedPreferences.getInt(
signal_sampling_frequency_key, -1), service);
}
if (key == null || key.equals(metric_units_key)) {
service.getSplitManager().setMetricUnits(sharedPreferences.getBoolean(
metric_units_key, true));
}
}
}
@@ -68,8 +68,6 @@ public class TrackRecordingService extends Service implements LocationListener {
private LocationManager locationManager;
private WakeLock wakeLock;
private int minRecordingInterval =
MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL;
private int minRecordingDistance =
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE;
private int maxRecordingDistance =
@@ -110,6 +108,8 @@ public class TrackRecordingService extends Service implements LocationListener {
private TaskExecuterManager signalManager;
private SplitManager splitManager;
private PreferenceManager prefManager;
/**
* The interval in milliseconds that we have requested to be notified of gps
* readings.
@@ -626,96 +626,7 @@ public class TrackRecordingService extends Service implements LocationListener {
public void onSharedPreferenceChanged(String key) {
Log.d(MyTracksConstants.TAG,
"TrackRecordingService.onSharedPreferenceChanged");
SharedPreferences sharedPreferences =
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
if (sharedPreferences == null) {
Log.w(MyTracksConstants.TAG,
"TrackRecordingService: Couldn't get shared preferences.");
return;
}
if (key == null
|| key.equals(getString(R.string.min_recording_distance_key))) {
minRecordingDistance = sharedPreferences.getInt(
getString(R.string.min_recording_distance_key),
MyTracksSettings.DEFAULT_MIN_RECORDING_DISTANCE);
Log.d(MyTracksConstants.TAG,
"TrackRecordingService: minRecordingDistance = "
+ minRecordingDistance);
}
if (key == null
|| key.equals(getString(R.string.max_recording_distance_key))) {
maxRecordingDistance = sharedPreferences.getInt(
getString(R.string.max_recording_distance_key),
MyTracksSettings.DEFAULT_MAX_RECORDING_DISTANCE);
}
if (key == null
|| key.equals(getString(R.string.min_recording_interval_key))) {
minRecordingInterval = sharedPreferences.getInt(
getString(R.string.min_recording_interval_key),
MyTracksSettings.DEFAULT_MIN_RECORDING_INTERVAL);
switch (minRecordingInterval) {
case -2:
// Battery Miser
// min: 30 seconds
// max: 5 minutes
// minDist: 5 meters Choose battery life over moving time accuracy.
locationListenerPolicy =
new AdaptiveLocationListenerPolicy(30000, 300000, 5);
break;
case -1:
// High Accuracy
// min: 1 second
// max: 30 seconds
// minDist: 0 meters get all updates to properly measure moving time.
locationListenerPolicy =
new AdaptiveLocationListenerPolicy(1000, 30000, 0);
break;
default:
locationListenerPolicy =
new AbsoluteLocationListenerPolicy(minRecordingInterval * 1000);
}
}
if (key == null
|| key.equals(getString(R.string.min_required_accuracy_key))) {
minRequiredAccuracy = sharedPreferences.getInt(
getString(R.string.min_required_accuracy_key),
MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY);
}
if (key == null
|| key.equals(getString(R.string.announcement_frequency_key))) {
announcementFrequency =
sharedPreferences.getInt(getString(R.string.announcement_frequency_key),
-1);
if (mTTSAvailable) {
if (announcementFrequency == -1) {
if (executer != null) {
executer.shutdown();
executer = null;
}
} else {
if (executer == null) {
SafeStatusAnnouncerTask announcer =
new SafeStatusAnnouncerTask(this);
executer = new PeriodicTaskExecuter(announcer, this);
}
executer.scheduleTask(announcementFrequency * 60000);
}
}
}
if (key == null || key.equals(getString(R.string.split_frequency_key))) {
splitManager.setSplitFrequency(
sharedPreferences.getInt(getString(R.string.split_frequency_key), 0));
}
if (key == null
|| key.equals(getString(R.string.signal_sampling_frequency_key))) {
signalManager.setFrequency(sharedPreferences.getInt(
getString(R.string.signal_sampling_frequency_key), -1), this);
}
if (key == null || key.equals(getString(R.string.metric_units_key))) {
splitManager.setMetricUnits(sharedPreferences.getBoolean(
getString(R.string.metric_units_key), true));
}
prefManager.onSharedPreferenceChanged(key);
if (isRecording) {
registerLocationListener();
@@ -748,6 +659,7 @@ public class TrackRecordingService extends Service implements LocationListener {
signalManager =
new TaskExecuterManager(-1, new SignalStrengthTask(this), this);
}
prefManager = new PreferenceManager(this);
onSharedPreferenceChanged(null);
restoreStats();
registerLocationListener();
@@ -983,4 +895,68 @@ public class TrackRecordingService extends Service implements LocationListener {
long getRecordingTrackId() {
return recordingTrackId;
}
public int getAnnouncementFrequency() {
return announcementFrequency;
}
public void setAnnouncementFrequency(int announcementFrequency) {
this.announcementFrequency = announcementFrequency;
if (mTTSAvailable) {
if (announcementFrequency == -1) {
if (executer != null) {
executer.shutdown();
executer = null;
}
} else {
if (executer == null) {
SafeStatusAnnouncerTask announcer =
new SafeStatusAnnouncerTask(this);
executer = new PeriodicTaskExecuter(announcer, this);
}
executer.scheduleTask(announcementFrequency * 60000);
}
}
}
public int getMaxRecordingDistance() {
return maxRecordingDistance;
}
public void setMaxRecordingDistance(int maxRecordingDistance) {
this.maxRecordingDistance = maxRecordingDistance;
}
public int getMinRecordingDistance() {
return minRecordingDistance;
}
public void setMinRecordingDistance(int minRecordingDistance) {
this.minRecordingDistance = minRecordingDistance;
}
public int getMinRequiredAccuracy() {
return minRequiredAccuracy;
}
public void setMinRequiredAccuracy(int minRequiredAccuracy) {
this.minRequiredAccuracy = minRequiredAccuracy;
}
public LocationListenerPolicy getLocationListenerPolicy() {
return locationListenerPolicy;
}
public void setLocationListenerPolicy(
LocationListenerPolicy locationListenerPolicy) {
this.locationListenerPolicy = locationListenerPolicy;
}
public SplitManager getSplitManager() {
return splitManager;
}
public TaskExecuterManager getSignalManager() {
return signalManager;
}
}