From 1de9b73aa0b81cc7964a1829b6cdc7d2aa70433b Mon Sep 17 00:00:00 2001 From: Sandor Dornbush Date: Wed, 18 Aug 2010 22:05:01 -0700 Subject: [PATCH] Address Rodrigo's comments. Add service preference manager. --- .../android/apps/mytracks/MyTracks.java | 6 +- .../android/apps/mytracks/MyTracksMap.java | 126 +++++--------- .../mytracks/services/PreferenceManager.java | 122 +++++++++++++ .../services/TrackRecordingService.java | 160 ++++++++---------- 4 files changed, 239 insertions(+), 175 deletions(-) create mode 100644 MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java index a0b8a46c2..142c74de4 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracks.java @@ -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 = diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java index a34bec3ac..f89bb6f98 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java @@ -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(); + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java new file mode 100644 index 000000000..a57691ff8 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java @@ -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)); + } + } +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java index 73efcdeca..65eebf418 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -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; + } }