diff --git a/MyTracks/res/values-ca/arrays.xml b/MyTracks/res/values-ca/arrays.xml
index 2eddecf5b..2bba332fa 100644
--- a/MyTracks/res/values-ca/arrays.xml
+++ b/MyTracks/res/values-ca/arrays.xml
@@ -112,9 +112,9 @@ limitations under the License.
- 3.1 miles (senyal GPS pobre)
-
-
- - Sense divisió
+
+
+ - Inactiu
- 100 km
- 50 km
- 25 km
@@ -130,8 +130,8 @@ limitations under the License.
- 1 min
-
- - No splitting
+
+ - Inactiu
- 100 mi
- 50 mi
- 25 mi
@@ -286,6 +286,8 @@ limitations under the License.
- Cap
+ - ANT+ Sensors
+ - SRM ANT+ Bridge
- Zephyr Bluetooth
diff --git a/MyTracks/res/values-de/arrays.xml b/MyTracks/res/values-de/arrays.xml
index ed7915fc8..f33ae9fe1 100644
--- a/MyTracks/res/values-de/arrays.xml
+++ b/MyTracks/res/values-de/arrays.xml
@@ -48,7 +48,6 @@ limitations under the License.
- 328 Fuß
-
- 50 m
@@ -113,9 +112,9 @@ limitations under the License.
- 3,1 Meilen (sehr schlechtes GPS-Signal)
-
-
- - Nicht zerteilen
+
+
+ - Aus
- 100 km
- 50 km
- 25 km
@@ -132,7 +131,7 @@ limitations under the License.
- - Nicht zerteilen
+ - Aus
- 100 Meilen
- 50 Meilen
- 25 Meilen
diff --git a/MyTracks/res/values-es/arrays.xml b/MyTracks/res/values-es/arrays.xml
index 25bd36439..2c9ac030a 100644
--- a/MyTracks/res/values-es/arrays.xml
+++ b/MyTracks/res/values-es/arrays.xml
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - Apagado
- - 1 min
- - 2 min
- - 5 min
- - 10 min
- - 15 min
- - 30 min
- - 60 min
-
-
- 1 m
@@ -112,9 +100,9 @@ limitations under the License.
- 3.1 miles (señal GPS débil)
-
-
- - No dividir
+
+
+ - Apagado
- 100 km
- 50 km
- 25 km
@@ -130,8 +118,8 @@ limitations under the License.
- 1 min
-
- - No dividir
+
+ - Apagado
- 100 mi
- 50 mi
- 25 mi
diff --git a/MyTracks/res/values-fr/arrays.xml b/MyTracks/res/values-fr/arrays.xml
index 0c9eedf72..18740a364 100644
--- a/MyTracks/res/values-fr/arrays.xml
+++ b/MyTracks/res/values-fr/arrays.xml
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - Absent
- - 1 min
- - 2 min
- - 5 min
- - 10 min
- - 15 min
- - 30 min
- - 60 min
-
-
- 1 m
@@ -112,10 +100,9 @@ limitations under the License.
- 3.1 miles (mauvais signal GPS)
-
-
-
- - Pas de séparation
+
+
+ - Absent
- 100 km
- 50 km
- 25 km
@@ -131,8 +118,8 @@ limitations under the License.
- 1 min
-
- - Pas de séparation
+
+ - Absent
- 100 mi
- 50 mi
- 25 mi
@@ -310,5 +297,5 @@ limitations under the License.
- Pont SRM ANT+
- Bluetooth Zephyr
-
+
diff --git a/MyTracks/res/values-it/arrays.xml b/MyTracks/res/values-it/arrays.xml
index 4b8e02cb5..9974d2fc2 100644
--- a/MyTracks/res/values-it/arrays.xml
+++ b/MyTracks/res/values-it/arrays.xml
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - Disattivato
- - 1 min
- - 2 min
- - 5 min
- - 10 min
- - 15 min
- - 30 min
- - 60 min
-
-
- 1 m
@@ -112,9 +100,9 @@ limitations under the License.
- 3.1 mi (segnale GPS debole)
-
-
- - Non dividere
+
+
+ - Disattivato
- 100 km
- 50 km
- 25 km
@@ -130,8 +118,8 @@ limitations under the License.
- 1 min
-
- - Non dividere
+
+ - Disattivato
- 100 mi
- 50 mi
- 25 mi
diff --git a/MyTracks/res/values-ja/arrays.xml b/MyTracks/res/values-ja/arrays.xml
index 582056996..31e45abee 100644
--- a/MyTracks/res/values-ja/arrays.xml
+++ b/MyTracks/res/values-ja/arrays.xml
@@ -15,19 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - 不使用
- - 1 分
- - 2 分
- - 5 分
- - 10 分
- - 15 分
- - 30 分
- - 60 分
-
-
-
+
- 1 m
- 2 m
@@ -48,7 +36,6 @@ limitations under the License.
- 328 ft
-
- 50 m
@@ -68,7 +55,6 @@ limitations under the License.
- 3.1 mi
-
- 電源節約 (動的制御)
@@ -89,7 +75,6 @@ limitations under the License.
- 30 分
-
- 10 m (GPS信号強度良好)
@@ -115,10 +100,9 @@ limitations under the License.
- 3.1 mi (GPS信号強度不良)
-
-
-
- - 分割なし
+
+
+ - 不使用
- 100 km
- 50 km
- 25 km
@@ -134,8 +118,8 @@ limitations under the License.
- 1 分
-
- - 分割なし
+
+ - 不使用
- 100 mi
- 50 mi
- 25 mi
@@ -294,4 +278,5 @@ limitations under the License.
- SRM ANT+ ブリッジ
- Zephyr Bluetooth
+
diff --git a/MyTracks/res/values-pl/arrays.xml b/MyTracks/res/values-pl/arrays.xml
index 80c7d0dbd..bf55da1a4 100644
--- a/MyTracks/res/values-pl/arrays.xml
+++ b/MyTracks/res/values-pl/arrays.xml
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - Brak
- - 1 min
- - 2 min
- - 5 min
- - 10 min
- - 15 min
- - 30 min
- - 60 min
-
-
- 1 m
@@ -112,9 +100,9 @@ limitations under the License.
- 3.1 mili (słaby sygnał GPS)
-
-
- - Brak dzielenia
+
+
+ - Brak
- 100 km
- 50 km
- 25 km
@@ -130,8 +118,8 @@ limitations under the License.
- 1 min
-
- - Brak dzielenia
+
+ - Brak
- 100 mi
- 50 mi
- 25 mi
@@ -146,7 +134,7 @@ limitations under the License.
- 2 min
- 1 min
-
+
- Nigdy
diff --git a/MyTracks/res/values-pt-rBR/arrays.xml b/MyTracks/res/values-pt-rBR/arrays.xml
index 8f442d0fd..60090ae40 100644
--- a/MyTracks/res/values-pt-rBR/arrays.xml
+++ b/MyTracks/res/values-pt-rBR/arrays.xml
@@ -15,21 +15,8 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - Desligado
- - 1 min
- - 2 min
- - 5 min
- - 10 min
- - 15 min
- - 30 min
- - 60 min
-
-
-
-
+
- 1 m
- 2 m
- 3 m
@@ -37,9 +24,9 @@ limitations under the License.
- 5 m (recomendada)
- 10 m
- 100 m
-
+
-
+
- 3 pés
- 6 pés
- 10 pés
@@ -47,31 +34,29 @@ limitations under the License.
- 16 pés (recomendado)
- 33 pés
- 328 pés
-
-
+
-
+
- 50 m
- 100 m
- 200 m (recomendado)
- 500 m
- 1000 m
- 5000 m
-
+
-
+
- 164 pés
- 328 pés
- 656 pés (recomendado)
- 1640 pés
- 0.6 milhas
- 3.1 milhas
-
-
+
-
+
- economia de bateria (adaptativo)
- alta precisão (adaptativo)
- máxima (recomendada)
@@ -88,11 +73,10 @@ limitations under the License.
- 10 min
- 15 min
- 30 min
-
-
+
-
+
- 10 m (sinal de GPS excelente)
- 20 m
- 50 m
@@ -102,9 +86,9 @@ limitations under the License.
- 1000 m
- 2000 m
- 5000 m (sinal de GPS ruim)
-
+
-
+
- 33 pés (sinal de GPS excelente)
- 66 pés
- 165 pés
@@ -114,12 +98,11 @@ limitations under the License.
- 0.6 milhas
- 1.2 milhas
- 3.1 milhas (sinal de GPS ruim)
-
+
-
-
-
- - Sem divisões
+
+
+ - Desligado
- 100 km
- 50 km
- 25 km
@@ -135,8 +118,8 @@ limitations under the License.
- 1 min
-
- - Sem divisões
+
+ - Desligado
- 100 mi
- 50 mi
- 25 mi
diff --git a/MyTracks/res/values-sv/arrays.xml b/MyTracks/res/values-sv/arrays.xml
index eb24d0ef3..fef8a4ec9 100644
--- a/MyTracks/res/values-sv/arrays.xml
+++ b/MyTracks/res/values-sv/arrays.xml
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - Av
- - 1 min
- - 2 min
- - 5 min
- - 10 min
- - 15 min
- - 30 min
- - 60 min
-
-
- 1 m
@@ -67,7 +55,6 @@ limitations under the License.
- 3.1 miles
-
- batterioptimerad (anpassningsbar)
@@ -113,9 +100,9 @@ limitations under the License.
- 3.1 miles (dålig GPS-signal)
-
-
- - Ingen delning
+
+
+ - Av
- 100 km
- 50 km
- 25 km
@@ -131,8 +118,8 @@ limitations under the License.
- 1 min
-
- - Ingen delning
+
+ - Av
- 100 mi
- 50 mi
- 25 mi
diff --git a/MyTracks/res/values-zh-rCN/arrays.xml b/MyTracks/res/values-zh-rCN/arrays.xml
index 48f15e956..e3108f9e2 100644
--- a/MyTracks/res/values-zh-rCN/arrays.xml
+++ b/MyTracks/res/values-zh-rCN/arrays.xml
@@ -15,18 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - 关闭
- - 1 分钟
- - 2 分钟
- - 5 分钟
- - 10 分钟
- - 15 分钟
- - 30 分钟
- - 60 分钟
-
-
- 1 米
@@ -112,9 +100,9 @@ limitations under the License.
- 3.1 英里 (糟糕的 GPS 信号)
-
-
- - 不分割
+
+
+ - 关闭
- 100 千米
- 50 千米
- 25 千米
@@ -130,8 +118,8 @@ limitations under the License.
- 1 分钟
-
- - 不分割
+
+ - 关闭
- 100 英里
- 50 英里
- 25 英里
@@ -155,6 +143,7 @@ limitations under the License.
- 15 分钟
- 总是
+
- 未知
diff --git a/MyTracks/res/values/arrays.xml b/MyTracks/res/values/arrays.xml
index d50dfd701..783668362 100644
--- a/MyTracks/res/values/arrays.xml
+++ b/MyTracks/res/values/arrays.xml
@@ -15,31 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
- - Off
- - 1 min
- - 2 min
- - 5 min
- - 10 min
- - 15 min
- - 30 min
- - 60 min
-
-
-
-
- - -1
- - 1
- - 2
- - 5
- - 10
- - 15
- - 30
- - 60
-
-
-
- 1 m
@@ -61,18 +36,6 @@ limitations under the License.
- 328 ft
-
-
- - 1
- - 2
- - 3
- - 4
- - 5
- - 10
- - 100
-
-
-
- 50 m
@@ -92,17 +55,6 @@ limitations under the License.
- 3.1 miles
-
-
- - 50
- - 100
- - 200
- - 500
- - 1000
- - 5000
-
-
-
- battery miser (adaptive)
@@ -123,27 +75,6 @@ limitations under the License.
- 30 min
-
-
- - -2
- - -1
- - 0
- - 2
- - 3
- - 4
- - 5
- - 10
- - 20
- - 30
- - 60
- - 120
- - 300
- - 480
- - 900
- - 1800
-
-
-
- 10 m (excellent GPS signal)
@@ -169,23 +100,9 @@ limitations under the License.
- 3.1 miles (poor GPS signal)
-
-
- - 10
- - 20
- - 50
- - 100
- - 200
- - 500
- - 1000
- - 2000
- - 5000
-
-
-
-
-
- - No splitting
+
+
+ - Off
- 100 km
- 50 km
- 25 km
@@ -201,8 +118,8 @@ limitations under the License.
- 1 min
-
- - No splitting
+
+ - Off
- 100 mi
- 50 mi
- 25 mi
@@ -218,24 +135,6 @@ limitations under the License.
- 1 min
-
-
- - 0
- - -100
- - -50
- - -25
- - -10
- - -5
- - -1
- - 60
- - 30
- - 15
- - 10
- - 5
- - 2
- - 1
-
-
- Never
@@ -245,16 +144,6 @@ limitations under the License.
- Always
-
-
- - 0
- - 5
- - 10
- - 15
- - -1
-
-
-
- unknown
@@ -383,14 +272,6 @@ limitations under the License.
- way point
-
-
- - GPX
- - KML
- - CSV
- - TCX
-
-
- None
- ANT+ Sensors
@@ -398,18 +279,4 @@ limitations under the License.
- Zephyr Bluetooth
-
-
- - @string/none
- - @string/ant_sensor_type
- - @string/srm_ant_bridge_sensor_type
- - @string/zephyr_sensor_type
-
-
-
-
- - @string/ant_sensor_type
- - @string/srm_ant_bridge_sensor_type
-
-
diff --git a/MyTracks/res/values/arrays_do_not_translate.xml b/MyTracks/res/values/arrays_do_not_translate.xml
new file mode 100644
index 000000000..d7d383a78
--- /dev/null
+++ b/MyTracks/res/values/arrays_do_not_translate.xml
@@ -0,0 +1,122 @@
+
+
+
+
+
+ - 10
+ - 20
+ - 50
+ - 100
+ - 200
+ - 500
+ - 1000
+ - 2000
+ - 5000
+
+
+
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 10
+ - 100
+
+
+
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 10
+ - 100
+
+
+
+ - 50
+ - 100
+ - 200
+ - 500
+ - 1000
+ - 5000
+
+
+
+ - -2
+ - -1
+ - 0
+ - 2
+ - 3
+ - 4
+ - 5
+ - 10
+ - 20
+ - 30
+ - 60
+ - 120
+ - 300
+ - 480
+ - 900
+ - 1800
+
+
+
+ - 0
+ - -100
+ - -50
+ - -25
+ - -10
+ - -5
+ - -1
+ - 60
+ - 30
+ - 15
+ - 10
+ - 5
+ - 2
+ - 1
+
+
+
+ - 0
+ - 5
+ - 10
+ - 15
+ - -1
+
+
+
+ - GPX
+ - KML
+ - CSV
+ - TCX
+
+
+
+ - @string/none
+ - @string/ant_sensor_type
+ - @string/srm_ant_bridge_sensor_type
+ - @string/zephyr_sensor_type
+
+
+
+ - @string/ant_sensor_type
+ - @string/srm_ant_bridge_sensor_type
+
+
diff --git a/MyTracks/res/xml/preferences.xml b/MyTracks/res/xml/preferences.xml
index e4d0b093f..d964f124b 100644
--- a/MyTracks/res/xml/preferences.xml
+++ b/MyTracks/res/xml/preferences.xml
@@ -48,8 +48,8 @@ limitations under the License.
android:key="@string/split_frequency_key"
android:title="@string/settings_split_frequency"
android:summary="@string/settings_split_frequency_summary"
- android:entries="@array/split_frequency_options"
- android:entryValues="@array/split_frequency_values"
+ android:entries="@array/task_frequency_options"
+ android:entryValues="@array/task_frequency_values"
android:defaultValue="0" />
pendingPoints = new ArrayList();
+ private TrackDataHub dataHub;
+
+ // Stats gathered from received data.
+ private double profileLength = 0;
+ private long startTime = -1;
+ private Location lastLocation;
+ private double trackMaxSpeed;
+
+ // Modes of operation
private Mode mode = Mode.BY_DISTANCE;
-
- /**
- * Utilities to deal with the database.
- */
- private MyTracksProviderUtils providerUtils;
+ private boolean metricUnits;
+ private boolean reportSpeed;
/*
* UI elements:
@@ -109,9 +81,6 @@ public class ChartActivity extends Activity implements
private LinearLayout busyPane;
private ZoomControls zoomControls;
- /** Handler for callbacks to the UI thread */
- private final Handler uiHandler = new Handler();
-
/**
* A runnable that can be posted to the UI thread. It will remove the spinner
* (if any), enable/disable zoom controls and orange pointer as appropriate
@@ -123,89 +92,17 @@ public class ChartActivity extends Activity implements
busyPane.setVisibility(View.GONE);
zoomControls.setIsZoomInEnabled(chartView.canZoomIn());
zoomControls.setIsZoomOutEnabled(chartView.canZoomOut());
- chartView.setShowPointer(selectedTrackIsRecording());
+ chartView.setShowPointer(dataHub.isRecordingSelected());
chartView.invalidate();
}
};
- /**
- * A runnable that can be posted to the UI thread. It will show the spinner.
- */
- private final Runnable showSpinner = new Runnable() {
- @Override
- public void run() {
- busyPane.setVisibility(View.VISIBLE);
- }
- };
-
- /**
- * An observer for the tracks provider. Will listen to new track points being
- * added and update the chart if necessary.
- */
- private ContentObserver observer;
-
- /**
- * An observer for the waypoints provider. Will listen to new way points being
- * added and update the chart if necessary.
- */
- private ContentObserver waypointObserver;
-
- /**
- * A thread with a looper. Post to updateTrackHandler to execute Runnables on
- * this thread.
- */
- private final HandlerThread updateTrackThread =
- new HandlerThread("updateTrackThread");
-
- /** Handler for updateTrackThread */
- private Handler updateTrackHandler;
-
- /**
- * A runnable that updates the profile from the provider.
- */
- private final Runnable updateTrackRunnable = new Runnable() {
- @Override
- public void run() {
- readNewTrackPoints();
- }
- };
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
- String key) {
- if (key != null) {
- if (key.equals(getString(R.string.selected_track_key))) {
- selectedTrackId =
- sharedPreferences.getLong(getString(R.string.selected_track_key),
- -1);
- readProfileAsync();
- } else if (key.equals(getString(R.string.metric_units_key))) {
- metricUnits =
- sharedPreferences.getBoolean(getString(R.string.metric_units_key),
- true);
- chartView.setMetricUnits(metricUnits);
- readProfileAsync();
- } else if (key.equals(getString(R.string.report_speed_key))) {
- reportSpeed =
- sharedPreferences.getBoolean(getString(R.string.report_speed_key),
- true);
- chartView.setReportSpeed(reportSpeed, this);
- readProfileAsync();
- } else if (key.equals(getString(R.string.recording_track_key))) {
- recordingTrackId =
- sharedPreferences.getLong(getString(R.string.recording_track_key),
- -1);
- runOnUiThread(updateChart);
- }
- }
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.w(TAG, "ChartActivity.onCreate");
super.onCreate(savedInstanceState);
MyTracks.getInstance().setChartActivity(this);
- providerUtils = MyTracksProviderUtils.Factory.get(this);
+ dataHub = MyTracks.getInstance().getDataHub();
// The volume we want to control is the Text-To-Speech volume
int volumeStream =
@@ -221,22 +118,6 @@ public class ChartActivity extends Activity implements
new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
layout.addView(chartView, params);
- SharedPreferences preferences =
- getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
- if (preferences != null) {
- selectedTrackId =
- preferences.getLong(getString(R.string.selected_track_key), -1);
- recordingTrackId =
- preferences.getLong(getString(R.string.recording_track_key), -1);
- metricUnits = preferences.getBoolean(getString(R.string.metric_units_key),
- true);
- chartView.setMetricUnits(metricUnits);
- reportSpeed = preferences.getBoolean(getString(R.string.report_speed_key),
- true);
- chartView.setReportSpeed(reportSpeed, this);
- preferences.registerOnSharedPreferenceChangeListener(this);
- }
-
busyPane = (LinearLayout) findViewById(R.id.elevation_busypane);
zoomControls = (ZoomControls) findViewById(R.id.elevation_zoom);
zoomControls.setOnZoomInClickListener(new View.OnClickListener() {
@@ -251,97 +132,20 @@ public class ChartActivity extends Activity implements
zoomOut();
}
});
-
- updateTrackThread.start();
- updateTrackHandler = new Handler(updateTrackThread.getLooper());
-
- // Register observer for the track point provider:
- Handler contentHandler = new Handler();
- observer = new ContentObserver(contentHandler) {
- @Override
- public void onChange(boolean selfChange) {
- Log.d(TAG, "ChartActivity: ContentObserver.onChange");
- // Check for any new locations and append them to the currently
- // recording track.
- if (recordingTrackId < 0) {
- // No track is being recorded. We should not be here.
- return;
- }
- if (selectedTrackId != recordingTrackId) {
- // No track, or one other than the recording track is selected, don't
- // bother.
- return;
- }
- // Update can potentially be lengthy, put it in its own thread:
- updateTrackHandler.post(updateTrackRunnable);
- super.onChange(selfChange);
- }
- };
-
- waypointObserver = new ContentObserver(contentHandler) {
- @Override
- public void onChange(boolean selfChange) {
- Log.d(TAG,
- "MyTracksMap: ContentObserver.onChange waypoints");
- if (selectedTrackId < 0) {
- return;
- }
- Thread t = new Thread() {
- @Override
- public void run() {
- readWaypoints();
- ChartActivity.this.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- chartView.invalidate();
- }
- });
- }
- };
- t.start();
- super.onChange(selfChange);
- }
- };
-
- readProfileAsync();
}
@Override
- protected void onPause() {
- super.onPause();
- unregisterContentObservers();
+ protected void onStart() {
+ super.onStart();
+
+ dataHub.registerTrackDataListener(this);
}
@Override
- protected void onResume() {
- super.onResume();
- // Make sure any updates that might have happened are propagated to this
- // activity:
- observer.onChange(false);
- waypointObserver.onChange(false);
- registerContentObservers();
- }
+ protected void onStop() {
+ dataHub.unregisterTrackDataListener(this);
- /**
- * Register the content observer for the map overlay.
- */
- private void registerContentObservers() {
- getContentResolver().registerContentObserver(TrackPointsColumns.CONTENT_URI,
- false/* notifyForDescendents */, observer);
- getContentResolver().registerContentObserver(WaypointsColumns.CONTENT_URI,
- false/* notifyForDescendents */, waypointObserver);
- }
-
- /**
- * Unregister the content observer for the map overlay.
- */
- private void unregisterContentObservers() {
- getContentResolver().unregisterContentObserver(observer);
- getContentResolver().unregisterContentObserver(waypointObserver);
- }
-
- private boolean selectedTrackIsRecording() {
- return selectedTrackId == recordingTrackId;
+ super.onStop();
}
private void zoomIn() {
@@ -360,7 +164,7 @@ public class ChartActivity extends Activity implements
if (this.mode != newMode) {
this.mode = newMode;
chartView.setMode(this.mode);
- readProfileAsync();
+ dataHub.reloadDataFor(this);
}
}
@@ -377,34 +181,6 @@ public class ChartActivity extends Activity implements
return chartView.getChartValueSeries(index).isEnabled();
}
- private void readWaypoints() {
- if (selectedTrackId < 0) {
- return;
- }
- Cursor cursor = null;
- chartView.clearWaypoints();
- try {
- // We will silently drop extra waypoints to make the app responsive.
- cursor =
- providerUtils.getWaypointsCursor(selectedTrackId, 0,
- Constants.MAX_DISPLAYED_TRACK_POINTS);
- if (cursor != null) {
- if (cursor.moveToFirst()) {
- do {
- Waypoint wpt = providerUtils.createWaypoint(cursor);
- chartView.addWaypoint(wpt);
- } while (cursor.moveToNext());
- }
- }
- } catch (RuntimeException e) {
- Log.w(TAG, "Caught an unexpected exception.", e);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
@@ -440,43 +216,41 @@ public class ChartActivity extends Activity implements
* This must be called in order for each point.
*
* @param location the location to get data for (this method takes ownership of that location)
- * @param track the track to get data from
* @param result the resulting point to fill out
* @return the previous location, now available for reuse
*/
- private Location getDataPoint(Location location, Track track, double[] result) {
+ private void fillDataPoint(Location location, double result[]) {
+ double timeOrDistance = Double.NaN,
+ elevation = Double.NaN,
+ speed = Double.NaN,
+ power = Double.NaN,
+ cadence = Double.NaN,
+ heartRate = Double.NaN;
+
if (location instanceof MyTracksLocation &&
((MyTracksLocation) location).getSensorDataSet() != null) {
SensorDataSet sensorData = ((MyTracksLocation) location).getSensorDataSet();
if (sensorData.hasPower()
&& sensorData.getPower().getState() == Sensor.SensorState.SENDING
&& sensorData.getPower().hasValue()) {
- result[3] = sensorData.getPower().getValue();
- } else {
- result[3] = Double.NaN;
+ power = sensorData.getPower().getValue();
}
if (sensorData.hasCadence()
&& sensorData.getCadence().getState() == Sensor.SensorState.SENDING
&& sensorData.getCadence().hasValue()) {
- result[4] = sensorData.getCadence().getValue();
- } else {
- result[4] = Double.NaN;
+ cadence = sensorData.getCadence().getValue();
}
if (sensorData.hasHeartRate()
&& sensorData.getHeartRate().getState() == Sensor.SensorState.SENDING
&& sensorData.getHeartRate().hasValue()) {
- result[5] = sensorData.getHeartRate().getValue();
- } else {
- result[5] = Double.NaN;
+ heartRate = sensorData.getHeartRate().getValue();
}
- } else {
- result[3] = Double.NaN;
- result[4] = Double.NaN;
- result[5] = Double.NaN;
}
+
+ // TODO: Account for segment splits?
switch (mode) {
case BY_DISTANCE:
- result[0] = profileLength;
+ timeOrDistance = profileLength;
if (lastLocation != null) {
double d = lastLocation.distanceTo(location);
if (metricUnits) {
@@ -491,7 +265,7 @@ public class ChartActivity extends Activity implements
// Base case
startTime = location.getTime();
}
- result[0] = (location.getTime() - startTime);
+ timeOrDistance = (location.getTime() - startTime);
break;
default:
Log.w(TAG, "ChartActivity unknown mode: " + mode);
@@ -500,7 +274,7 @@ public class ChartActivity extends Activity implements
elevationBuffer.setNext(metricUnits
? location.getAltitude()
: location.getAltitude() * UnitConversions.M_TO_FT);
- result[1] = elevationBuffer.getAverage();
+ elevation = elevationBuffer.getAverage();
if (lastLocation == null) {
if (Math.abs(location.getSpeed() - 128) > 1) {
@@ -509,151 +283,134 @@ public class ChartActivity extends Activity implements
} else if (TripStatisticsBuilder.isValidSpeed(
location.getTime(), location.getSpeed(), lastLocation.getTime(),
lastLocation.getSpeed(), speedBuffer)
- && (location.getSpeed() <= track.getStatistics().getMaxSpeed())) {
+ && (location.getSpeed() <= trackMaxSpeed)) {
speedBuffer.setNext(location.getSpeed());
}
- result[2] = speedBuffer.getAverage() * 3.6;
+ speed = speedBuffer.getAverage() * 3.6;
if (!metricUnits) {
- result[2] *= UnitConversions.KM_TO_MI;
+ speed *= UnitConversions.KM_TO_MI;
}
- if (!reportSpeed && (result[2] != 0)) {
- // Format as hours per unit
- result[2] = (60.0 / result[2]);
+ if (!reportSpeed) {
+ if (speed != 0) {
+ // Format as hours per unit
+ speed = (60.0 / speed);
+ } else {
+ speed = Double.NaN;
+ }
}
- Location oldLastLocation = lastLocation;
+ // Keep a copy so the location can be reused.
lastLocation = location;
- if (oldLastLocation == null) {
- // No previous location, but return a blank one for reuse
- return new MyTracksLocation("");
+ if (result != null) {
+ result[0] = timeOrDistance;
+ result[1] = elevation;
+ result[2] = speed;
+ result[3] = power;
+ result[4] = cadence;
+ result[5] = heartRate;
}
-
- return oldLastLocation;
}
- /**
- * Sets the chart data points reading from the provider. This is non-blocking.
- */
- private void readProfileAsync() {
- chartView.reset();
- updateTrackHandler.post(new Runnable() {
+ @Override
+ public void onProviderStateChange(ProviderState state) {
+ // We don't care.
+ }
+
+ @Override
+ public void onCurrentLocationChanged(Location loc) {
+ // We don't care.
+ }
+
+ @Override
+ public void onCurrentHeadingChanged(double heading) {
+ // We don't care.
+ }
+
+ @Override
+ public void onSelectedTrackChanged(Track track, boolean isRecording) {
+ Log.e(TAG, "Visible", new Throwable());
+ runOnUiThread(new Runnable() {
+ @Override
public void run() {
- runOnUiThread(showSpinner);
- readProfile();
- readWaypoints();
- runOnUiThread(updateChart);
+ busyPane.setVisibility(View.VISIBLE);
}
});
}
- /**
- * Reads the track profile from the provider. This is a blocking function and
- * should not be run from the UI thread.
- */
- private void readProfile() {
+ @Override
+ public void onTrackUpdated(Track track) {
+ trackMaxSpeed = track.getStatistics().getMaxSpeed();
+ }
+
+ @Override
+ public void clearTrackPoints() {
profileLength = 0;
lastLocation = null;
startTime = -1;
- if (selectedTrackId < 0) {
- return;
- }
- Track track = providerUtils.getTrack(selectedTrackId);
- if (track == null) {
- return;
- }
- lastSeenLocationId = track.getStartId();
- final ArrayList theData = readPointsToList(track);
- runOnUiThread(new Runnable() {
- public void run() {
- chartView.setDataPoints(theData);
- }
- });
+ elevationBuffer.reset();
+ speedBuffer.reset();
+ chartView.reset();
+ pendingPoints.clear();
}
- /**
- * Read all new track points.
- */
- private void readNewTrackPoints() {
- Log.i(TAG, "MyTracks: Updating chart last seen: " + lastSeenLocationId);
- Track track = providerUtils.getTrack(recordingTrackId);
- if (track == null) {
- Log.w(TAG, "MyTracks: track not found");
- return;
+ @Override
+ public void onNewTrackPoint(Location loc) {
+ if (LocationUtils.isValidLocation(loc)) {
+ double[] point = new double[6];
+ fillDataPoint(loc, point);
+ pendingPoints.add(point);
}
- chartView.addDataPoints(readPointsToList(track));
- uiHandler.post(new Runnable() {
- public void run() {
- chartView.invalidate();
- }
- });
- Log.i(TAG, "MyTracks: Updated chart last seen: " + lastSeenLocationId);
}
- /**
- * Get the frequency at which points should be displayed.
- * Limit the number of chart readings. Ideally we would want around 1024.
- * @param track The track which will be displayed.
- * @return The inverse of the frequency of points to be displayed.
- */
- private int getSamplingFrequency(Track track) {
- long totalLocations = track.getStopId() - track.getStartId();
- return Math.max(1, (int) (totalLocations / 1024.0));
+ @Override
+ public void onSampledOutTrackPoint(Location loc) {
+ // Still account for the point in the smoothing buffers.
+ fillDataPoint(loc, null);
}
- private Cursor getLocationsCursor(long lastLocationRead) {
- return providerUtils.getLocationsCursor(selectedTrackId, lastLocationRead, BUFFER_SIZE, false);
+ @Override
+ public void onSegmentSplit() {
+ // Do nothing.
}
- /**
- * Read all of the points to a list.
- * @param track The track which will be displayed.
- * @return
- */
- private ArrayList readPointsToList(Track track) {
- Cursor cursor = null;
- long lastLocationRead = lastSeenLocationId;
- int points = 0;
- int chartSamplingFrequency = getSamplingFrequency(track);
- ArrayList result = new ArrayList();
- // Need two locations so we can keep track of the last location.
- Location location = new MyTracksLocation("");
- try {
- while (lastSeenLocationId < track.getStopId()) {
- cursor = getLocationsCursor(lastLocationRead);
- if (cursor != null) {
- elevationBuffer.reset();
- speedBuffer.reset();
- if (cursor.moveToFirst()) {
- final int idColumnIdx = cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
- while (cursor.moveToNext()) {
- points++;
- providerUtils.fillLocation(cursor, location);
- if (MyTracksUtils.isValidLocation(location)) {
- lastLocationRead = lastSeenLocationId =
- cursor.getLong(idColumnIdx);
- // TODO Can we be smarter about choosing 3 or 6 entries?
- double[] point = new double[6];
- location = getDataPoint(location, track, point);
- if (points % chartSamplingFrequency == 0) {
- result.add(point);
- }
- }
- }
- } else {
- lastLocationRead += BUFFER_SIZE;
- }
- } else {
- lastLocationRead += BUFFER_SIZE;
- }
- cursor.close();
- cursor = null;
- }
- return result;
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
+ @Override
+ public void onNewTrackPointsDone() {
+ chartView.addDataPoints(pendingPoints);
+ pendingPoints.clear();
+ runOnUiThread(updateChart);
+ }
+
+ @Override
+ public void clearWaypoints() {
+ chartView.clearWaypoints();
+ }
+
+ @Override
+ public void onNewWaypoint(Waypoint wpt) {
+ chartView.addWaypoint(wpt);
+ }
+
+ @Override
+ public void onNewWaypointsDone() {
+ runOnUiThread(updateChart);
+ }
+
+ @Override
+ public boolean onUnitsChanged(boolean metric) {
+ this.metricUnits = metric;
+
+ chartView.setMetricUnits(metric);
+
+ return true; // Reload data
+ }
+
+ @Override
+ public boolean onReportSpeedChanged(boolean reportSpeed) {
+ this.reportSpeed = reportSpeed;
+
+ chartView.setReportSpeed(reportSpeed, this);
+
+ return true; // Reload data
}
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java b/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
index 71d382c66..7a7f6e950 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/MapActivity.java
@@ -19,81 +19,53 @@ import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
-import com.google.android.apps.mytracks.content.TrackPointsColumns;
import com.google.android.apps.mytracks.content.Waypoint;
-import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.ApiFeatures;
import com.google.android.apps.mytracks.util.GeoRect;
-import com.google.android.apps.mytracks.util.MyTracksUtils;
+import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.maps.GeoPoint;
-import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.mytracks.R;
-import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.hardware.GeomagneticField;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.location.LocationProvider;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
import android.provider.Settings;
import android.util.Log;
import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
-import android.view.Window;
-import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
+import android.view.Window;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
-import android.widget.Toast;
/**
* The map view activity of the MyTracks application.
*
* @author Leif Hendrik Wilden
+ * @author Rodrigo Damazio
*/
-public class MyTracksMap extends MapActivity
+public class MapActivity extends com.google.android.maps.MapActivity
implements View.OnTouchListener, View.OnClickListener,
- SharedPreferences.OnSharedPreferenceChangeListener {
- private static final int TRACKPOINT_BUFFER_SIZE = 1024;
+ TrackDataListener {
// Saved instance state keys:
// ---------------------------
- public static final String KEY_CURRENT_LOCATION = "currentLocation";
- public static final String KEY_KEEP_MY_LOCATION_VISIBLE =
- "keepMyLocationVisible";
- public static final String KEY_HAVE_GOOD_FIX = "haveGoodFix";
+ private static final String KEY_CURRENT_LOCATION = "currentLocation";
+ private static final String KEY_KEEP_MY_LOCATION_VISIBLE = "keepMyLocationVisible";
- /**
- * The ID of the currently selected track (or -1 if nothing selected).
- */
- private long selectedTrackId = -1;
-
- /**
- * The id of the currently recording track.
- */
- private long recordingTrackId = -1;
+ private TrackDataHub dataHub;
/**
* True if the map should be scrolled so that the pointer is always in the
@@ -101,152 +73,18 @@ public class MyTracksMap extends MapActivity
*/
private boolean keepMyLocationVisible;
- /**
- * Id of the first location that was seen when reading tracks from the
- * provider.
- */
- private long firstSeenLocationId = -1;
-
- /**
- * Id of the last location that was seen when reading tracks from the
- * provider. This is used to determine which locations are new compared to the
- * last time the mapOverlay was updated.
- */
- private long lastSeenLocationId = -1;
-
- /**
- * Magnetic variation.
- */
- private double variation;
-
- /**
- * From the shared preferences.
- */
- private int minRequiredAccuracy =
- MyTracksSettings.DEFAULT_MIN_REQUIRED_ACCURACY;
-
- /**
- * True, if the application thinks it has a good fix, i.e. accuracy is better
- * than the required accuracy.
- */
- private boolean haveGoodFix;
-
/**
* The current pointer location.
+ * This is kept to quickly center on it when the user requests.
*/
private Location currentLocation;
- /**
- * A thread with a looper. Post to updateTrackHandler to execute
- * {@link Runnable}s on this thread.
- */
- private HandlerThread updateTrackThread;
-
- /**
- * Handler for updateTrackThread.
- */
- private Handler updateTrackHandler;
-
- private MyTracksProviderUtils providerUtils;
-
- private SharedPreferences sharedPreferences;
-
- /**
- * A runnable that updates the track from the provider (looking for points
- * added after "lastSeenLocationId").
- */
- private final Runnable updateTrackRunnable = new Runnable() {
- @Override
- public void run() {
- if (!isATrackSelected()) {
- return;
- }
-
- readAllNewTrackPoints();
- }
- };
-
- /**
- * A runnable that restores all track points from the provider.
- */
- private Runnable restoreTrackRunnable = new Runnable() {
- @Override
- public void run() {
- if (!isATrackSelected()) {
- return;
- }
-
- mapOverlay.clearPoints();
- firstSeenLocationId = -1;
- lastSeenLocationId = -1;
- readAllNewTrackPoints();
- }
- };
-
- /**
- * A runnable that restores all waypoints from the provider.
- */
- private final Runnable restoreWaypointsRunnable = new Runnable() {
- @Override
- public void run() {
- if (!isATrackSelected()) {
- return;
- }
-
- Cursor cursor = null;
- mapOverlay.clearWaypoints();
- try {
- // We will silently drop extra waypoints to make the app responsive.
- // TODO: Try to only load the waypoints in the view port.
- cursor = providerUtils.getWaypointsCursor(
- selectedTrackId, 0,
- Constants.MAX_DISPLAYED_WAYPOINTS_POINTS);
- if (cursor != null && cursor.moveToFirst()) {
- do {
- Waypoint waypoint = providerUtils.createWaypoint(cursor);
- if (MyTracksUtils.isValidLocation(waypoint.getLocation())) {
- mapOverlay.addWaypoint(waypoint);
- }
- } while (cursor.moveToNext());
- }
- } catch (RuntimeException e) {
- Log.w(TAG, "Caught an unexpected exception.", e);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- mapView.postInvalidate();
- }
- };
-
- /**
- * A runnable intended to be posted to the {@code #updateTrackThread} after
- * the selected track changes. It will post to the UI thread to update
- * the screen elements and move the map to show the selected track.
- */
- private final Runnable setSelectedTrackRunnable = new Runnable() {
- @Override
- public void run() {
- uiHandler.post(new Runnable() {
- public void run() {
- showTrack(selectedTrackId);
- mapOverlay.setTrackDrawingEnabled(isATrackSelected());
- mapOverlay.setShowEndMarker(!isRecordingSelected());
- mapView.invalidate();
- busyPane.setVisibility(View.GONE);
- updateOptionsButton();
- }
- });
- }
- };
-
// UI elements:
// -------------
private RelativeLayout screen;
private MapView mapView;
- private MyTracksOverlay mapOverlay;
+ private MapOverlay mapOverlay;
private LinearLayout messagePane;
private TextView messageText;
private LinearLayout busyPane;
@@ -255,14 +93,6 @@ public class MyTracksMap extends MapActivity
private MenuItem myLocation;
private MenuItem toggleLayers;
- private SensorManager sensorManager;
- private LocationManager locationManager;
- private ContentObserver observer;
- private ContentObserver waypointObserver;
-
- /** Handler for callbacks to the UI thread */
- private final Handler uiHandler = new Handler();
-
/**
* We are not displaying driving directions. Just an arbitrary track that is
* not associated to any licensed mapping data. Therefore it should be okay to
@@ -287,7 +117,7 @@ public class MyTracksMap extends MapActivity
@Override
public void onCreate(Bundle bundle) {
- Log.d(TAG, "MyTracksMap.onCreate");
+ Log.d(TAG, "MapActivity.onCreate");
super.onCreate(bundle);
// The volume we want to control is the Text-To-Speech volume
@@ -295,7 +125,7 @@ public class MyTracksMap extends MapActivity
new StatusAnnouncerFactory(ApiFeatures.getInstance()).getVolumeStream();
setVolumeControlStream(volumeStream);
- providerUtils = MyTracksProviderUtils.Factory.get(this);
+ dataHub = MyTracks.getInstance().getDataHub();
// We don't need a window title bar:
requestWindowFeature(Window.FEATURE_NO_TITLE);
@@ -310,9 +140,10 @@ public class MyTracksMap extends MapActivity
screen = (RelativeLayout) findViewById(R.id.screen);
mapView = (MapView) findViewById(R.id.map);
mapView.requestFocus();
- mapOverlay = new MyTracksOverlay(this);
+ mapOverlay = new MapOverlay(this);
mapView.getOverlays().add(mapOverlay);
mapView.setOnTouchListener(this);
+ mapView.setBuiltInZoomControls(true);
messagePane = (LinearLayout) findViewById(R.id.messagepane);
messageText = (TextView) findViewById(R.id.messagetext);
busyPane = (LinearLayout) findViewById(R.id.busypane);
@@ -320,186 +151,18 @@ public class MyTracksMap extends MapActivity
optionsBtn.setOnCreateContextMenuListener(contextMenuListener);
optionsBtn.setOnClickListener(this);
-
- setupZoomControls();
-
- // Get the sensor and location managers:
- sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
- locationManager =
- (LocationManager) getSystemService(Context.LOCATION_SERVICE);
-
- updateTrackThread = new HandlerThread("updateTrackThread");
- updateTrackThread.start();
- updateTrackHandler = new Handler(updateTrackThread.getLooper());
-
- // Register observer for the track point provider:
- Handler contentHandler = new Handler();
- observer = new ContentObserver(contentHandler) {
- @Override
- public void onChange(boolean selfChange) {
- Log.d(TAG, "MyTracksMap: ContentObserver.onChange");
- if (!isRecordingSelected()) {
- // No track, or one other than the recording track is selected,
- // don't bother.
- return;
- }
- // Update can potentially be lengthy, put it in its own thread:
- updateTrackHandler.post(updateTrackRunnable);
- super.onChange(selfChange);
- }
- };
-
- waypointObserver = new ContentObserver(contentHandler) {
- @Override
- public void onChange(boolean selfChange) {
- Log.d(TAG,
- "MyTracksMap: ContentObserver.onChange waypoints");
- if (!isATrackSelected()) {
- return;
- }
- updateTrackHandler.post(restoreWaypointsRunnable);
- super.onChange(selfChange);
- }
- };
-
- // Read shared preferences and register change listener.
- sharedPreferences = getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
- if (sharedPreferences != null) {
- reloadSharedPreferences(sharedPreferences, null);
- updateOptionsButton();
- sharedPreferences.registerOnSharedPreferenceChangeListener(this);
- }
- }
-
- @Override
- protected void onDestroy() {
- Log.d(TAG, "MyTracksMap.onDestroy");
-
- if (updateTrackThread != null) {
- ApiFeatures.getInstance().getApiPlatformAdapter().stopHandlerThread(
- updateTrackThread);
- }
- if (sharedPreferences != null) {
- sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
- }
-
- super.onDestroy();
- }
-
- /**
- * Returns whether there's a track currently selected for display.
- */
- private boolean isATrackSelected() {
- return selectedTrackId >= 0;
- }
-
- /**
- * Returns whether we're currently recording the same track that's selected
- * for display.
- */
- private boolean isRecordingSelected() {
- return isATrackSelected() && selectedTrackId == recordingTrackId;
- }
-
- protected void setupZoomControls() {
- mapView.setBuiltInZoomControls(true);
- }
-
- @Override
- protected void onStart() {
- // Called after onCreate or onStop.
- // Will be followed by onRestart.
- Log.d(TAG, "MyTracksMap.onStart");
- super.onStart();
- }
-
- @Override
- protected void onStop() {
- // Called when activity is no longer visible to user.
- // Next either onStart, onDestroy or nothing will be called.
- // This method may never be called in low memory situations.
- Log.d(TAG, "MyTracksMap.onStop");
- super.onStop();
- }
-
- @Override
- protected void onRestart() {
- // Called when the current activity is being re-displayed.
- // Will be followed by onResume.
- Log.d(TAG, "MyTracksMap.onRestart");
- super.onRestart();
- }
-
- @Override
- protected void onPause() {
- // Called when activity is going into the background, but has not (yet) been
- // killed. Shouldn't block longer than approx. 2 seconds.
- Log.d(TAG, "MyTracksMap.onPause");
- unregisterLocationAndSensorListeners();
- unregisterContentObservers();
- super.onPause();
- }
-
- @Override
- protected void onResume() {
- // Called when the current activity is being displayed or re-displayed
- // to the user.
- Log.d(TAG, "MyTracksMap.onResume");
- super.onResume();
-
- // Reload all preferences as they might have changed since last run.
- reloadSharedPreferences(sharedPreferences, null);
-
- // Make sure any updates that might have happened are propagated to the
- // Map overlay:
- observer.onChange(false);
- waypointObserver.onChange(false);
-
- registerContentObservers();
- registerLocationAndSensorListeners();
-
- if (locationManager.isProviderEnabled(Constants.GPS_PROVIDER)) {
- messageText.setText(R.string.wait_for_fix);
- messagePane.setOnClickListener(null);
- } else {
- messageText.setText(R.string.status_enable_gps);
- messagePane.setVisibility(View.VISIBLE);
- messagePane.setOnClickListener(this);
- screen.requestLayout();
- }
-
- // While this activity was paused the user may have deleted the selected
- // track. In that case the map overlay needs to be cleared:
- if (isATrackSelected() && !providerUtils.trackExists(selectedTrackId)) {
- // The recording track must have been deleted meanwhile.
- mapOverlay.setTrackDrawingEnabled(false);
- mapView.invalidate();
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- Log.d(TAG, "MyTracksMap.onSaveInstanceState");
- outState.putBoolean(KEY_HAVE_GOOD_FIX, haveGoodFix);
- outState.putBoolean(KEY_KEEP_MY_LOCATION_VISIBLE, keepMyLocationVisible);
- if (currentLocation != null) {
- outState.putParcelable(KEY_CURRENT_LOCATION, currentLocation);
- }
- super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle bundle) {
- Log.d(TAG, "MyTracksMap.onRestoreInstanceState");
+ Log.d(TAG, "MapActivity.onRestoreInstanceState");
if (bundle != null) {
super.onRestoreInstanceState(bundle);
- haveGoodFix = bundle.getBoolean(KEY_HAVE_GOOD_FIX, false);
keepMyLocationVisible =
bundle.getBoolean(KEY_KEEP_MY_LOCATION_VISIBLE, false);
if (bundle.containsKey(KEY_CURRENT_LOCATION)) {
currentLocation = (Location) bundle.getParcelable(KEY_CURRENT_LOCATION);
if (currentLocation != null) {
- setVariation(currentLocation);
showCurrentLocation();
}
} else {
@@ -508,98 +171,42 @@ public class MyTracksMap extends MapActivity
}
}
+ @Override
+ protected void onStart() {
+ Log.d(TAG, "MapActivity.onStart");
+ super.onStart();
+
+ dataHub.registerTrackDataListener(this);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ Log.d(TAG, "MapActivity.onSaveInstanceState");
+ outState.putBoolean(KEY_KEEP_MY_LOCATION_VISIBLE, keepMyLocationVisible);
+ if (currentLocation != null) {
+ outState.putParcelable(KEY_CURRENT_LOCATION, currentLocation);
+ }
+ super.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onStop() {
+ Log.d(TAG, "MapActivity.onStop");
+
+ dataHub.unregisterTrackDataListener(this);
+
+ super.onStop();
+ }
+
// Utility functions:
// -------------------
- /**
- * Toggles between satellite and map view.
- */
- public void toggleLayer() {
- mapView.setSatellite(!mapView.isSatellite());
- }
-
- /**
- * Registers to receive location updates from the GPS location provider and
- * sensor updated from the compass.
- */
- void registerLocationAndSensorListeners() {
- if (locationManager != null) {
- LocationProvider gpsProvider =
- locationManager.getProvider(Constants.GPS_PROVIDER);
- if (gpsProvider == null) {
- alert(getString(R.string.error_no_gps_location_provider));
- return;
- } else {
- Log.d(TAG, "MyTracksMap: Using location provider "
- + gpsProvider.getName());
- }
- locationManager.requestLocationUpdates(gpsProvider.getName(),
- 0 /*minTime*/, 0 /*minDist*/, locationListener);
- try {
- locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
- 1000 * 60 * 5 /*minTime*/, 0 /*minDist*/, locationListener);
- } catch (RuntimeException e) {
- // If anything at all goes wrong with getting a cell location do not
- // abort. Cell location is not essential to this app.
- Log.w(TAG,
- "Could not register network location listener.");
- }
- }
- if (sensorManager == null) {
- return;
- }
- Sensor compass = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
- if (compass == null) {
- return;
- }
- Log.d(TAG,
- "MyTracksMap: Now registering sensor listeners.");
- sensorManager.registerListener(
- sensorListener, compass, SensorManager.SENSOR_DELAY_UI);
- }
-
- /**
- * Unregisters all location and sensor listeners
- */
- void unregisterLocationAndSensorListeners() {
- if (locationManager != null) {
- Log.d(TAG,
- "MyTracksMap: Now unregistering location listeners.");
- locationManager.removeUpdates(locationListener);
- }
- if (sensorManager != null) {
- Log.d(TAG,
- "MyTracksMap: Now unregistering sensor listeners.");
- sensorManager.unregisterListener(sensorListener);
- }
- }
-
- /**
- * Registers the content observer for the map overlay.
- */
- private void registerContentObservers() {
- getContentResolver().registerContentObserver(
- TrackPointsColumns.CONTENT_URI, false /* notifyForDescendents */,
- observer);
- getContentResolver().registerContentObserver(
- WaypointsColumns.CONTENT_URI, false /* notifyForDescendents */,
- waypointObserver);
- }
-
- /**
- * Unregisters the content observer for the map overlay.
- */
- private void unregisterContentObservers() {
- getContentResolver().unregisterContentObserver(observer);
- getContentResolver().unregisterContentObserver(waypointObserver);
- }
-
/**
* Shows the options button if a track is selected, or hide it if not.
*/
- private void updateOptionsButton() {
+ private void updateOptionsButton(boolean trackSelected) {
optionsBtn.setVisibility(
- isATrackSelected() ? View.VISIBLE : View.INVISIBLE);
+ trackSelected ? View.VISIBLE : View.INVISIBLE);
}
/**
@@ -628,7 +235,7 @@ public class MyTracksMap extends MapActivity
GeoRect r = new GeoRect(center, latSpan, lonSpan);
r.top += margin;
- GeoPoint geoPoint = MyTracksUtils.getGeoPoint(location);
+ GeoPoint geoPoint = LocationUtils.getGeoPoint(location);
return r.contains(geoPoint);
}
@@ -641,25 +248,30 @@ public class MyTracksMap extends MapActivity
return;
}
mapOverlay.setMyLocation(currentLocation);
- mapView.invalidate();
+ mapView.postInvalidate();
if (keepMyLocationVisible && !locationIsVisible(currentLocation)) {
+ GeoPoint geoPoint = LocationUtils.getGeoPoint(currentLocation);
MapController controller = mapView.getController();
- GeoPoint geoPoint = MyTracksUtils.getGeoPoint(currentLocation);
controller.animateTo(geoPoint);
}
+
+ }
+
+ @Override
+ public void onTrackUpdated(Track track) {
+ // We don't care.
}
/**
* Zooms and pans the map so that the given track is visible.
*
- * @param trackId a given track ID
+ * @param track the track
*/
- public void showTrack(long trackId) {
+ private void zoomMapToBoundaries(Track track) {
if (mapView == null) {
return;
}
- Track track = providerUtils.getTrack(trackId);
if (track == null || track.getNumberOfPoints() < 2) {
return;
}
@@ -677,7 +289,7 @@ public class MyTracksMap extends MapActivity
GeoPoint center = new GeoPoint(
bottom + latSpanE6 / 2,
left + lonSpanE6 / 2);
- if (MyTracksUtils.isValidGeoPoint(center)) {
+ if (LocationUtils.isValidGeoPoint(center)) {
mapView.getController().setCenter(center);
mapView.getController().zoomToSpan(latSpanE6, lonSpanE6);
}
@@ -688,6 +300,7 @@ public class MyTracksMap extends MapActivity
* Zooms and pans the map so that the given waypoint is visible.
*/
public void showWaypoint(long waypointId) {
+ MyTracksProviderUtils providerUtils = MyTracksProviderUtils.Factory.get(this);
Waypoint wpt = providerUtils.getWaypoint(waypointId);
if (wpt != null && wpt.getLocation() != null) {
keepMyLocationVisible = false;
@@ -700,86 +313,29 @@ public class MyTracksMap extends MapActivity
}
}
- /**
- * Sets the selected track and zoom and pan the map so that it is visible.
- *
- * @param trackId a given track id
- */
- public void setSelectedTrack(final long trackId) {
- Log.d(TAG, "MyTracksMap.setSelectedTrack: "
- + "selectedTrackId = " + selectedTrackId + ", trackId = " + trackId);
+ @Override
+ public void onSelectedTrackChanged(final Track track, final boolean isRecording) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ boolean trackSelected = track != null;
+ updateOptionsButton(trackSelected);
- if (selectedTrackId == trackId) {
- // Selected track did not change, nothing to do.
- mapOverlay.setTrackDrawingEnabled(isATrackSelected());
- updateOptionsButton();
- mapView.invalidate();
- return;
- }
+ mapOverlay.setTrackDrawingEnabled(trackSelected);
- if (trackId < 0) {
- // Remove selection.
- selectedTrackId = -1;
- mapOverlay.setTrackDrawingEnabled(false);
- mapOverlay.clearWaypoints();
- updateOptionsButton();
- mapView.invalidate();
- return;
- }
-
- busyPane.setVisibility(View.VISIBLE);
- selectedTrackId = trackId;
- loadSelectedTrack();
+ if (trackSelected) {
+ busyPane.setVisibility(View.VISIBLE);
+
+ zoomMapToBoundaries(track);
+
+ mapOverlay.setShowEndMarker(!isRecording);
+ busyPane.setVisibility(View.GONE);
+ }
+ mapView.invalidate();
+ }
+ });
}
- private void loadSelectedTrack() {
- updateTrackHandler.post(restoreTrackRunnable);
- updateTrackHandler.post(restoreWaypointsRunnable);
- updateTrackHandler.post(setSelectedTrackRunnable);
- }
-
- /**
- * Displays an alert for a few seconds.
- *
- * @param txt The text to be displayed
- */
- public void alert(String txt) {
- Toast.makeText(this, txt, Toast.LENGTH_LONG).show();
- }
-
- public void launchMyLocationSettings() {
- startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
- }
-
- public void setVariation(Location location) {
- long timestamp = location.getTime();
- if (timestamp == 0) {
- // Hack for Samsung phones which don't populate the time field
- timestamp = System.currentTimeMillis();
- }
-
- GeomagneticField field = new GeomagneticField(
- (float) location.getLatitude(),
- (float) location.getLongitude(),
- (float) location.getAltitude(),
- timestamp);
- variation = field.getDeclination();
-
- Log.d(TAG,
- "MyTracksMap: Variation reset to " + variation + " degrees.");
- }
-
- public MyTracksOverlay getMapOverlay() {
- return mapOverlay;
- }
-
- public MapView getMapView() {
- return mapView;
- }
-
- // Event listeners:
- // -----------------
-
private final OnCreateContextMenuListener contextMenuListener =
new OnCreateContextMenuListener() {
@Override
@@ -788,7 +344,7 @@ public class MyTracksMap extends MapActivity
menu.setHeaderTitle(R.string.tracklist_this_track);
menu.add(0, Constants.MENU_EDIT, 0,
R.string.tracklist_edit_track);
- if (!isRecordingSelected()) {
+ if (!dataHub.isRecordingSelected()) {
menu.add(0, Constants.MENU_SEND_TO_GOOGLE, 0,
R.string.tracklist_send_to_google);
SubMenu share = menu.addSubMenu(0, Constants.MENU_SHARE, 0,
@@ -825,12 +381,10 @@ public class MyTracksMap extends MapActivity
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (!super.onMenuItemSelected(featureId, item)) {
- if (isATrackSelected()) {
- MyTracks.getInstance().onActivityResult(
- Constants.getActionFromMenuId(item.getItemId()), RESULT_OK,
- new Intent());
- return true;
- }
+ MyTracks.getInstance().onActivityResult(
+ Constants.getActionFromMenuId(item.getItemId()), RESULT_OK,
+ new Intent());
+ return true;
}
return false;
}
@@ -858,24 +412,15 @@ public class MyTracksMap extends MapActivity
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Constants.MENU_MY_LOCATION: {
- Location loc = MyTracks.getInstance().getCurrentLocation();
- if (loc != null) {
- currentLocation = loc;
- setVariation(currentLocation);
- mapOverlay.setMyLocation(loc);
- mapView.invalidate();
- GeoPoint geoPoint = MyTracksUtils.getGeoPoint(loc);
- MapController controller = mapView.getController();
- controller.animateTo(geoPoint);
- if (mapView.getZoomLevel() < 18) {
- controller.setZoom(18);
- }
- keepMyLocationVisible = true;
+ dataHub.forceUpdateLocation();
+ keepMyLocationVisible = true;
+ if (mapView.getZoomLevel() < 18) {
+ mapView.getController().setZoom(18);
}
return true;
}
case Constants.MENU_TOGGLE_LAYERS: {
- toggleLayer();
+ mapView.setSatellite(!mapView.isSatellite());
return true;
}
}
@@ -885,7 +430,7 @@ public class MyTracksMap extends MapActivity
@Override
public void onClick(View v) {
if (v == messagePane) {
- launchMyLocationSettings();
+ startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
} else if (v == optionsBtn) {
optionsBtn.performLongClick();
}
@@ -906,191 +451,121 @@ public class MyTracksMap extends MapActivity
}
@Override
- public void onSharedPreferenceChanged(
- final SharedPreferences sharedPreferences, final String key) {
- Log.d(TAG,
- "MyTracksMap.onSharedPreferenceChanged: " + key);
- if (key != null) {
- uiHandler.post(new Runnable() {
- @Override
- public void run() {
- reloadSharedPreferences(sharedPreferences, key);
+ public void onProviderStateChange(ProviderState state) {
+ final int messageId;
+ final boolean bindClick;
+ switch (state) {
+ case DISABLED:
+ messageId = R.string.status_enable_gps;
+ bindClick = true;
+ break;
+ case NO_FIX:
+ case BAD_FIX:
+ messageId = R.string.wait_for_fix;
+ bindClick = false;
+ break;
+ case GOOD_FIX:
+ // Nothing to show.
+ messageId = -1;
+ bindClick = false;
+ break;
+ default:
+ throw new IllegalArgumentException("Unexpected state: " + state);
+ }
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (messageId != -1) {
+ messageText.setText(messageId);
+ messagePane.setVisibility(View.VISIBLE);
+
+ if (bindClick) {
+ messagePane.setOnClickListener(MapActivity.this);
+ } else {
+ messagePane.setOnClickListener(null);
+ }
+ } else {
+ messagePane.setVisibility(View.GONE);
}
- });
- }
- }
- private final LocationListener locationListener = new LocationListener() {
- @Override
- public void onProviderEnabled(String provider) {
- if (provider.equals(Constants.GPS_PROVIDER)) {
- messageText.setText(R.string.wait_for_fix);
- }
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- if (provider.equals(Constants.GPS_PROVIDER)) {
- messageText.setText(R.string.status_enable_gps);
- messagePane.setVisibility(View.VISIBLE);
- messagePane.setOnClickListener(MyTracksMap.this);
screen.requestLayout();
}
+ });
+ }
+
+ @Override
+ public void onCurrentLocationChanged(Location location) {
+ if (!location.getProvider().equals(Constants.GPS_PROVIDER)) {
+ Log.d(TAG,
+ "MapActivity: Network location update received (provider '" + location.getProvider() + "'.");
}
- @Override
- public void onLocationChanged(Location location) {
- if (location.getProvider().equals(Constants.GPS_PROVIDER)) {
- // Recalculate the variation if there was a jump in location > 1km:
- if (currentLocation == null ||
- location.distanceTo(currentLocation) > 1000) {
- setVariation(location);
- }
- currentLocation = location;
- boolean haveGoodFixNow =
- currentLocation.getAccuracy() < minRequiredAccuracy;
- if (haveGoodFixNow != haveGoodFix) {
- haveGoodFix = haveGoodFixNow;
- messagePane.setVisibility(haveGoodFix ? View.GONE : View.VISIBLE);
- screen.requestLayout();
- }
- showCurrentLocation();
- } else {
- Log.d(TAG,
- "MyTracksMap: Network location update received.");
+ currentLocation = location;
+ showCurrentLocation();
+ }
+
+ @Override
+ public void onCurrentHeadingChanged(double heading) {
+ synchronized (this) {
+ if (mapOverlay.setHeading((float) heading)) {
+ mapView.postInvalidate();
}
}
-
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- if (provider.equals(Constants.GPS_PROVIDER)) {
- switch (status) {
- case LocationProvider.OUT_OF_SERVICE:
- case LocationProvider.TEMPORARILY_UNAVAILABLE:
- haveGoodFix = false;
- messagePane.setVisibility(View.VISIBLE);
- screen.requestLayout();
- break;
- }
- }
- }
- };
-
- private final SensorEventListener sensorListener = new SensorEventListener() {
- @Override
- public void onSensorChanged(SensorEvent se) {
- synchronized (this) {
- float magneticHeading = se.values[0];
- double heading = magneticHeading + variation;
- if (mapOverlay.setHeading((float) heading)) {
- mapView.invalidate();
- }
- }
- }
-
- @Override
- public void onAccuracyChanged(Sensor s, int accuracy) {
- // do nothing
- }
- };
-
- private void reloadSharedPreferences(SharedPreferences sharedPreferences,
- String key) {
- 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.recording_track_key))) {
- recordingTrackId = sharedPreferences.getLong(
- getString(R.string.recording_track_key), -1);
- }
- if (key == null || key.equals(getString(R.string.selected_track_key))) {
- setSelectedTrack(sharedPreferences.getLong(
- getString(R.string.selected_track_key), -1));
- }
-
- // Show end marker if the track has been selected and is not recording.
- // Note: This check must be *after* a call to setSelectedTrack(...) above.
- if (isATrackSelected()) {
- mapOverlay.setShowEndMarker(!isRecordingSelected());
- mapView.postInvalidate();
- }
}
- private void readAllNewTrackPoints() {
- int numPoints = mapOverlay.getNumLocations();
- if (numPoints >= Constants.MAX_DISPLAYED_TRACK_POINTS) {
- // We're about to exceed the maximum allowed number of points, so reload
- // the whole track with fewer points (the sampling frequency will be
- // lower).
- loadSelectedTrack();
- return;
+ @Override
+ public void clearWaypoints() {
+ mapOverlay.clearWaypoints();
+ }
+
+ @Override
+ public void onNewWaypoint(Waypoint waypoint) {
+ if (LocationUtils.isValidLocation(waypoint.getLocation())) {
+ // TODO: Optimize locking inside addWaypoint
+ mapOverlay.addWaypoint(waypoint);
}
- // Keep a copy of selectedTrackId, because it can change asynchronously.
- long currentSelectedTrackId = selectedTrackId;
- long lastStoredLocationId =
- providerUtils.getLastLocationId(currentSelectedTrackId);
- int samplingFrequency = -1;
- Location location = new Location("");
- while (currentSelectedTrackId == selectedTrackId) {
- Cursor cursor = null;
- try {
- cursor = providerUtils.getLocationsCursor(currentSelectedTrackId,
- lastSeenLocationId + 1, TRACKPOINT_BUFFER_SIZE, false);
- if (cursor == null || !cursor.moveToFirst()) {
- // No (more) data
- break;
- }
+ }
- final int idColumnIdx = cursor.getColumnIndexOrThrow(
- TrackPointsColumns._ID);
- do {
- long locationId = cursor.getLong(idColumnIdx);
- lastSeenLocationId = locationId;
- if (firstSeenLocationId == -1) {
- // This was our first point, keep its ID
- firstSeenLocationId = locationId;
- }
- if (samplingFrequency == -1) {
- // Now we already have at least one point, calculate the sampling
- // frequency
- long numTotalPoints = lastStoredLocationId - firstSeenLocationId;
- samplingFrequency = (int) (1 + numTotalPoints
- / Constants.TARGET_DISPLAYED_TRACK_POINTS);
- // TODO: This shouldn't happen after adding currentSelectedTrackId,
- // but just to be safe until we have 100% confidence.
- if (samplingFrequency <= 0) {
- Log.w(TAG,
- "readAllNewTrackPoints: samplingFreq <= 0, numTotalPoints = "
- + numTotalPoints + ", trackId = " + currentSelectedTrackId);
- samplingFrequency = 1;
- }
- }
-
- providerUtils.fillLocation(cursor, location);
-
- // Include a point if it fits one of the following criteria:
- // - Has the mod for the sampling frequency (includes first point).
- // - Is the last point and we are not recording this track.
- // - The point is a segment split
- if (numPoints % samplingFrequency == 0 ||
- (!isRecordingSelected() && locationId == lastStoredLocationId) ||
- !MyTracksUtils.isValidLocation(location)) {
- // No need to allocate a new location (we can safely reuse the existing).
- mapOverlay.addLocation(location);
- }
-
- numPoints++;
- } while (cursor.moveToNext() &&
- currentSelectedTrackId == selectedTrackId);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
+ @Override
+ public void onNewWaypointsDone() {
mapView.postInvalidate();
}
+
+ @Override
+ public void clearTrackPoints() {
+ mapOverlay.clearPoints();
+ }
+
+ @Override
+ public void onNewTrackPoint(Location loc) {
+ mapOverlay.addLocation(loc);
+ }
+
+ @Override
+ public void onSegmentSplit() {
+ mapOverlay.addSegmentSplit();
+ }
+
+ @Override
+ public void onSampledOutTrackPoint(Location loc) {
+ // We don't care.
+ }
+
+ @Override
+ public void onNewTrackPointsDone() {
+ mapView.postInvalidate();
+ }
+
+ @Override
+ public boolean onUnitsChanged(boolean metric) {
+ // We don't care.
+ return false;
+ }
+
+ @Override
+ public boolean onReportSpeedChanged(boolean reportSpeed) {
+ // We don't care.
+ return false;
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java
index 2471001eb..8d0458e34 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/SettingsActivity.java
@@ -266,9 +266,6 @@ public class SettingsActivity extends PreferenceActivity {
final ListPreference minRequiredAccuracy =
(ListPreference) findPreference(
getString(R.string.min_required_accuracy_key));
- final ListPreference splitFrequency =
- (ListPreference) findPreference(
- getString(R.string.split_frequency_key));
minRecordingDistance.setEntries(isMetric
? R.array.min_recording_distance_options
@@ -279,9 +276,16 @@ public class SettingsActivity extends PreferenceActivity {
minRequiredAccuracy.setEntries(isMetric
? R.array.min_required_accuracy_options
: R.array.min_required_accuracy_options_ft);
- splitFrequency.setEntries(isMetric
- ? R.array.split_frequency_options
- : R.array.split_frequency_options_ft);
+ setTaskOptions(isMetric, R.string.announcement_frequency_key);
+ setTaskOptions(isMetric, R.string.split_frequency_key);
+ }
+
+ private void setTaskOptions(boolean isMetric, int listId) {
+ final ListPreference taskFrequency =
+ (ListPreference) findPreference(getString(listId));
+ taskFrequency.setEntries(isMetric
+ ? R.array.task_frequency_options
+ : R.array.task_frequency_options_ft);
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
index 6b547836f..9b245915a 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/StatsActivity.java
@@ -17,26 +17,15 @@ package com.google.android.apps.mytracks;
import static com.google.android.apps.mytracks.Constants.TAG;
-import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
-import com.google.android.apps.mytracks.content.MyTracksProviderUtilsImpl;
import com.google.android.apps.mytracks.content.Track;
-import com.google.android.apps.mytracks.content.TracksColumns;
-import com.google.android.apps.mytracks.content.WaypointsColumns;
+import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.util.ApiFeatures;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.database.ContentObserver;
import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.location.LocationProvider;
import android.os.Bundle;
-import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
@@ -44,66 +33,39 @@ import android.view.MenuItem;
import android.view.Window;
import android.widget.ScrollView;
import android.widget.TextView;
-import android.widget.Toast;
/**
* An activity that displays track statistics to the user.
*
* @author Sandor Dornbush
+ * @author Rodrigo Damazio
*/
-public class StatsActivity extends Activity
- implements OnSharedPreferenceChangeListener {
-
+public class StatsActivity extends Activity implements TrackDataListener {
private StatsUtilities utils;
private UIUpdateThread thread;
- private ContentObserver observer;
-
- /**
- * The id of the currently selected track.
- */
- private long selectedTrackId = -1;
-
- /**
- * The id of the currently recording track.
- */
- private long recordingTrackId = -1;
-
/**
* The start time of the selected track.
*/
private long startTime = -1;
- /**
- * True if distances should be displayed in metric units (from shared
- * preferences).
- */
- private boolean metricUnits = true;
-
- /**
- * True if pace should be displayed as dist/time (from shared preferences).
- */
- private boolean displaySpeed = true;
-
- /**
- * true if activity has resumed and is on top
- */
- private boolean activityOnTop = false;
-
/**
* If true, the statistics for the current segment are shown, otherwise
* for the full track.
*/
private boolean showCurrentSegment = false;
- private MyTracksProviderUtils providerUtils;
+ private TrackDataHub dataHub;
/**
* A runnable for posting to the UI thread. Will update the total time field.
*/
private final Runnable updateResults = new Runnable() {
public void run() {
- updateTotalTime();
+ if (dataHub.isRecordingSelected()) {
+ utils.setTime(R.id.total_time_register,
+ System.currentTimeMillis() - startTime);
+ }
}
};
@@ -121,13 +83,11 @@ public class StatsActivity extends Activity
public void run() {
Log.i(TAG, "Started UI update thread");
while (MyTracks.getInstance().isRecording()) {
- long sleeptime = 1000;
runOnUiThread(updateResults);
try {
- Thread.sleep(sleeptime);
+ Thread.sleep(1000L);
} catch (InterruptedException e) {
- Log.w(TAG,
- "StatsActivity: Caught exception on sleep.", e);
+ Log.w(TAG, "StatsActivity: Caught exception on sleep.", e);
break;
}
}
@@ -140,9 +100,9 @@ public class StatsActivity extends Activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ dataHub = MyTracks.getInstance().getDataHub();
utils = new StatsUtilities(this);
- providerUtils = new MyTracksProviderUtilsImpl(getContentResolver());
-
+
// The volume we want to control is the Text-To-Speech volume
int volumeStream =
new StatusAnnouncerFactory(ApiFeatures.getInstance()).getVolumeStream();
@@ -153,40 +113,10 @@ public class StatsActivity extends Activity
setContentView(R.layout.stats);
- Handler contentHandler = new Handler();
- observer = new ContentObserver(contentHandler) {
- @Override
- public void onChange(boolean selfChange) {
- Log.d(TAG, "StatsActivity: ContentObserver.onChange");
- restoreStats();
- super.onChange(selfChange);
- }
- };
-
ScrollView sv = ((ScrollView) findViewById(R.id.scrolly));
sv.setScrollBarStyle(ScrollView.SCROLLBARS_OUTSIDE_INSET);
- SharedPreferences preferences =
- getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
- if (preferences != null) {
- selectedTrackId = preferences.getLong(
- getString(R.string.selected_track_key), -1);
- recordingTrackId = preferences.getLong(
- getString(R.string.recording_track_key), -1);
- metricUnits = preferences.getBoolean(
- getString(R.string.metric_units_key), true);
- displaySpeed =
- preferences.getBoolean(getString(R.string.report_speed_key), true);
- checkLiveTrack();
- restoreStats();
- showUnknownLocation();
- preferences.registerOnSharedPreferenceChangeListener(this);
- }
- utils.setMetricUnits(metricUnits);
- utils.setReportSpeed(displaySpeed);
- utils.updateUnits();
- utils.setSpeedLabel(R.id.speed_label, R.string.speed, R.string.pace_label);
- utils.setSpeedLabels();
+ showUnknownLocation();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
@@ -196,74 +126,49 @@ public class StatsActivity extends Activity
}
@Override
- protected void onPause() {
- unregisterLocationListener();
+ protected void onStart() {
+ dataHub.registerTrackDataListener(this);
+
+ super.onStart();
+ }
+
+ @Override
+ protected void onStop() {
+ dataHub.unregisterTrackDataListener(this);
+
if (thread != null) {
thread.interrupt();
thread = null;
}
- getContentResolver().unregisterContentObserver(observer);
- activityOnTop = false;
- super.onPause();
+
+ super.onStop();
}
@Override
- protected void onResume() {
- activityOnTop = true;
- checkLiveTrack();
- restoreStats();
- showUnknownLocation();
- super.onResume();
+ public boolean onUnitsChanged(boolean metric) {
+ utils.setMetricUnits(metric);
+ updateLabels();
+
+ return true; // Reload data
}
@Override
- public void onSharedPreferenceChanged(
- final SharedPreferences sharedPreferences, final String key) {
- Log.d(TAG,
- "StatsActivity: onSharedPreferences changed " + key);
- if (key != null) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (key.equals(getString(R.string.selected_track_key))) {
- selectedTrackId =
- sharedPreferences.getLong(
- getString(R.string.selected_track_key),
- -1);
- checkLiveTrack();
- restoreStats();
- showUnknownLocation();
- } else if (key.equals(getString(R.string.recording_track_key))) {
- recordingTrackId =
- sharedPreferences.getLong(
- getString(R.string.recording_track_key),
- -1);
- checkLiveTrack();
- restoreStats();
- showUnknownLocation();
- } else if (key.equals(getString(R.string.metric_units_key))) {
- metricUnits =
- sharedPreferences.getBoolean(
- getString(R.string.metric_units_key), true);
- utils.setMetricUnits(metricUnits);
- utils.updateUnits();
- restoreStats();
- } else if (key.equals(getString(R.string.report_speed_key))) {
- displaySpeed =
- sharedPreferences.getBoolean(
- getString(R.string.report_speed_key),
- true);
- utils.setReportSpeed(displaySpeed);
- utils.updateUnits();
- utils.setSpeedLabel(
- R.id.speed_label, R.string.speed, R.string.pace_label);
- Log.w(TAG, "Setting speed labels");
- utils.setSpeedLabels();
- restoreStats();
- }
- }
- });
- }
+ public boolean onReportSpeedChanged(boolean displaySpeed) {
+ utils.setReportSpeed(displaySpeed);
+ updateLabels();
+
+ return true; // Reload data
+ }
+
+ private void updateLabels() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ utils.updateUnits();
+ utils.setSpeedLabel(R.id.speed_label, R.string.speed, R.string.pace_label);
+ utils.setSpeedLabels();
+ }
+ });
}
@Override
@@ -291,137 +196,12 @@ public class StatsActivity extends Activity
switch (item.getItemId()) {
case Constants.MENU_CURRENT_SEGMENT:
showCurrentSegment = !showCurrentSegment;
- restoreStats();
+ // TODO: Re-read only the data that interests us
return true;
}
return super.onOptionsItemSelected(item);
}
- private final LocationListener locationListener = new LocationListener() {
- @Override
- public void onLocationChanged(Location l) {
- if (selectedTrackIsRecording()) {
- showLocation(l);
- }
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- // Do nothing
- }
-
- @Override
- public void onProviderEnabled(String provider) {
- // Do nothing
- }
-
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- // Do nothing
- }
- };
-
- /**
- * Registers to receive location updates from the GPS location provider.
- */
- private void registerLocationListener() {
- LocationManager locationManager =
- (LocationManager) getSystemService(Context.LOCATION_SERVICE);
- if (locationManager != null) {
- LocationProvider gpsProvider =
- locationManager.getProvider(Constants.GPS_PROVIDER);
- if (gpsProvider == null) {
- Toast.makeText(this, getString(R.string.error_no_gps_location_provider),
- Toast.LENGTH_LONG).show();
- return;
- } else {
- Log.d(TAG, "StatsActivity: Using location provider "
- + gpsProvider.getName());
- }
- locationManager.requestLocationUpdates(gpsProvider.getName(),
- 0/*minTime*/, 0/*minDist*/, locationListener);
- }
- }
-
- /**
- * Unregisters all location listener.
- */
- private void unregisterLocationListener() {
- LocationManager locationManager =
- (LocationManager) getSystemService(Context.LOCATION_SERVICE);
- if (locationManager != null) {
- locationManager.removeUpdates(locationListener);
- }
- }
-
- /**
- * @return true if the selected track is the currently recording track
- */
- private boolean selectedTrackIsRecording() {
- return MyTracks.getInstance().isRecording()
- && selectedTrackId == recordingTrackId;
- }
-
- /**
- * Reads values for selected tracks from provider and update the UI.
- */
- private void restoreStats() {
- if (selectedTrackId < 0) {
- utils.setAllToUnknown();
- return;
- }
-
- Track track = providerUtils.getTrack(selectedTrackId);
- if (track == null || track.getStatistics() == null) {
- utils.setAllToUnknown();
- return;
- }
-
- startTime = track.getStatistics().getStartTime();
- if (!selectedTrackIsRecording()) {
- utils.setTime(R.id.total_time_register,
- track.getStatistics().getTotalTime());
- }
- utils.setAllStats(track.getStatistics());
- }
-
- /**
- * Checks if this activity needs to update live track data or not.
- * If so, make sure that:
- * a) a thread keeps updating the total time
- * b) a location listener is registered
- * c) a content observer is registered
- * Otherwise unregister listeners, observers, and kill update thread.
- */
- private void checkLiveTrack() {
- final boolean isRecording = selectedTrackIsRecording();
- final boolean startThread =
- (thread == null) && isRecording && activityOnTop;
- final boolean killThread =
- (thread != null) && (!isRecording || !activityOnTop);
- if (startThread) {
- thread = new UIUpdateThread();
- thread.start();
- getContentResolver().registerContentObserver(
- TracksColumns.CONTENT_URI, false, observer);
- getContentResolver().registerContentObserver(
- WaypointsColumns.CONTENT_URI, false, observer);
- registerLocationListener();
- } else if (killThread) {
- thread.interrupt();
- thread = null;
- getContentResolver().unregisterContentObserver(observer);
- unregisterLocationListener();
- }
- }
-
- public void updateTotalTime() {
- if (selectedTrackIsRecording()) {
- utils.setTime(R.id.total_time_register,
- System.currentTimeMillis() - startTime);
- }
- }
-
/**
* Updates the given location fields (latitude, longitude, altitude) and all
* other fields.
@@ -441,4 +221,112 @@ public class StatsActivity extends Activity
utils.setUnknown(R.id.longitude_register);
utils.setUnknown(R.id.speed_register);
}
+
+ @Override
+ public void onSelectedTrackChanged(Track track, boolean isRecording) {
+ /*
+ * Checks if this activity needs to update live track data or not.
+ * If so, make sure that:
+ * a) a thread keeps updating the total time
+ * b) a location listener is registered
+ * c) a content observer is registered
+ * Otherwise unregister listeners, observers, and kill update thread.
+ */
+ final boolean startThread = (thread == null) && isRecording;
+ final boolean killThread = (thread != null) && (!isRecording);
+ if (startThread) {
+ thread = new UIUpdateThread();
+ thread.start();
+ } else if (killThread) {
+ thread.interrupt();
+ thread = null;
+ }
+
+ if (track == null || track.getStatistics() == null) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ utils.setAllToUnknown();
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onCurrentLocationChanged(Location loc) {
+ if (dataHub.isRecordingSelected()) {
+ showLocation(loc);
+ }
+ }
+
+ @Override
+ public void onCurrentHeadingChanged(double heading) {
+ // We don't care.
+ }
+
+ @Override
+ public void onProviderStateChange(ProviderState state) {
+ switch (state) {
+ case DISABLED:
+ case NO_FIX:
+ showUnknownLocation();
+ break;
+ }
+ }
+
+ @Override
+ public void onTrackUpdated(final Track track) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ startTime = track.getStatistics().getStartTime();
+ if (!dataHub.isRecordingSelected()) {
+ utils.setTime(R.id.total_time_register,
+ track.getStatistics().getTotalTime());
+ showUnknownLocation();
+ }
+ utils.setAllStats(track.getStatistics());
+ }
+ });
+ }
+
+ @Override
+ public void clearWaypoints() {
+ // We don't care.
+ }
+
+ @Override
+ public void onNewWaypoint(Waypoint wpt) {
+ // We don't care.
+ }
+
+ @Override
+ public void onNewWaypointsDone() {
+ // We don't care.
+ }
+
+ @Override
+ public void clearTrackPoints() {
+ // We don't care.
+ }
+
+ @Override
+ public void onNewTrackPoint(Location loc) {
+ // We don't care.
+ }
+
+ @Override
+ public void onSegmentSplit() {
+ // We don't care.
+ }
+
+ @Override
+ public void onSampledOutTrackPoint(Location loc) {
+ // We don't care.
+ }
+
+ @Override
+ public void onNewTrackPointsDone() {
+ // We don't care.
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/TrackDataHub.java b/MyTracks/src/com/google/android/apps/mytracks/TrackDataHub.java
index d165f0e1e..d0e37e5e1 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/TrackDataHub.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/TrackDataHub.java
@@ -607,7 +607,7 @@ public class TrackDataHub {
if (key.equals(RECORDING_TRACK_KEY)) {
recordingTrackId = sharedPreferences.getLong(RECORDING_TRACK_KEY, -1);
} else if (key.equals(MIN_REQUIRED_ACCURACY_KEY)) {
- minRequiredAccuracy = sharedPreferences.getInt(RECORDING_TRACK_KEY,
+ minRequiredAccuracy = sharedPreferences.getInt(MIN_REQUIRED_ACCURACY_KEY,
Constants.DEFAULT_MIN_REQUIRED_ACCURACY);
} else if (key.equals(METRIC_UNITS_KEY)) {
useMetricUnits = 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 88abfeee6..02bdf6638 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
@@ -33,6 +33,7 @@ import com.google.android.apps.mytracks.services.sensors.SensorManager;
import com.google.android.apps.mytracks.services.sensors.SensorManagerFactory;
import com.google.android.apps.mytracks.services.tasks.PeriodicTask;
import com.google.android.apps.mytracks.services.tasks.PeriodicTaskExecuter;
+import com.google.android.apps.mytracks.services.tasks.SplitTask;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.stats.TripStatisticsBuilder;
@@ -190,8 +191,6 @@ public class TrackRecordingService extends Service implements LocationListener {
/**
* The frequency of status announcements.
*/
- private int announcementFrequency = -1;
-
private ExecutorService executerServce;
/*
@@ -667,6 +666,8 @@ public class TrackRecordingService extends Service implements LocationListener {
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+ setUpAnnouncer();
+ this.splitExecuter = new PeriodicTaskExecuter(this, new SplitTask());
prefManager = new PreferenceManager(this);
registerLocationListener();
@@ -702,32 +703,20 @@ public class TrackRecordingService extends Service implements LocationListener {
private void setUpAnnouncer() {
Log.d(TAG, "TrackRecordingService.setUpAnnouncer: "
+ announcementExecuter);
- if (announcementFrequency != -1 && recordingTrackId != -1) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (announcementExecuter == null) {
- StatusAnnouncerFactory statusAnnouncerFactory =
- new StatusAnnouncerFactory(ApiFeatures.getInstance());
- PeriodicTask announcer = statusAnnouncerFactory.create(
- TrackRecordingService.this);
- if (announcer == null) {
- return;
- }
-
- // TODO: Either use TaskExecuterManager everywhere, or get rid of it
- announcementExecuter = new PeriodicTaskExecuter(
- TrackRecordingService.this, announcer);
- }
- announcementExecuter.setTaskFrequency(announcementFrequency * 60000);
- }
- });
+ StatusAnnouncerFactory statusAnnouncerFactory =
+ new StatusAnnouncerFactory(ApiFeatures.getInstance());
+ PeriodicTask announcer = statusAnnouncerFactory.create(
+ TrackRecordingService.this);
+ if (announcer == null) {
+ return;
}
+
+ announcementExecuter = new PeriodicTaskExecuter(
+ TrackRecordingService.this, announcer);
}
- private void shutdownAnnouncer() {
- Log.d(TAG, "TrackRecordingService.shutdownAnnouncer: "
- + announcementExecuter);
+ private void shutdownExecuters() {
+ Log.d(TAG, "TrackRecordingService.shutdownExecuters");
if (announcementExecuter != null) {
try {
announcementExecuter.shutdown();
@@ -735,6 +724,13 @@ public class TrackRecordingService extends Service implements LocationListener {
announcementExecuter = null;
}
}
+ if (splitExecuter != null) {
+ try {
+ splitExecuter.shutdown();
+ } finally {
+ splitExecuter = null;
+ }
+ }
}
@Override
@@ -750,11 +746,7 @@ public class TrackRecordingService extends Service implements LocationListener {
timer.cancel();
timer.purge();
unregisterLocationListener();
- shutdownAnnouncer();
- announcementExecuter.shutdown();
- announcementExecuter = null;
- splitExecuter.shutdown();
- splitExecuter = null;
+ shutdownExecuters();
if (sensorManager != null) {
sensorManager.shutdown();
sensorManager = null;
@@ -1109,12 +1101,9 @@ public class TrackRecordingService extends Service implements LocationListener {
waypointStatsBuilder = new TripStatisticsBuilder(startTime);
waypointStatsBuilder.setMinRecordingDistance(minRecordingDistance);
currentWaypointId = insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
- setUpAnnouncer();
length = 0;
showNotification();
registerLocationListener();
- announcementExecuter.restore();
- splitExecuter.restore();
sensorManager = SensorManagerFactory.getSensorManager(this);
if (sensorManager != null) {
sensorManager.onStartTrack();
@@ -1129,6 +1118,8 @@ public class TrackRecordingService extends Service implements LocationListener {
// Notify the world that we're now recording.
sendTrackBroadcast(
R.string.track_started_broadcast_action, recordingTrackId);
+ announcementExecuter.restore();
+ splitExecuter.restore();
return recordingTrackId;
}
@@ -1139,7 +1130,7 @@ public class TrackRecordingService extends Service implements LocationListener {
throw new IllegalStateException("No recording track in progress!");
}
- shutdownAnnouncer();
+ shutdownExecuters();
isRecording = false;
Track recordingTrack = providerUtils.getTrack(recordingTrackId);
if (recordingTrack != null) {
@@ -1199,19 +1190,6 @@ public class TrackRecordingService extends Service implements LocationListener {
this.recordingTrackId = recordingTrackId;
}
- public int getAnnouncementFrequency() {
- return announcementFrequency;
- }
-
- public void setAnnouncementFrequency(int announcementFrequency) {
- this.announcementFrequency = announcementFrequency;
- if (announcementFrequency == -1) {
- shutdownAnnouncer();
- } else {
- setUpAnnouncer();
- }
- }
-
public int getMaxRecordingDistance() {
return maxRecordingDistance;
}
@@ -1257,12 +1235,24 @@ public class TrackRecordingService extends Service implements LocationListener {
this.autoResumeTrackTimeout = autoResumeTrackTimeout;
}
+ public void setAnnouncementFrequency(int announcementFrequency) {
+ if (announcementExecuter != null) {
+ announcementExecuter.setTaskFrequency(announcementFrequency);
+ }
+ }
+
public void setSplitFrequency(int frequency) {
- splitExecuter.setTaskFrequency(frequency);
+ if (splitExecuter != null) {
+ splitExecuter.setTaskFrequency(frequency);
+ }
}
public void setMetricUnits(boolean metric) {
- announcementExecuter.setMetricUnits(metric);
- splitExecuter.setMetricUnits(metric);
+ if (announcementExecuter != null) {
+ announcementExecuter.setMetricUnits(metric);
+ }
+ if (splitExecuter != null) {
+ splitExecuter.setMetricUnits(metric);
+ }
}
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskExecuter.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskExecuter.java
index ab2cc5f32..984612999 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskExecuter.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/PeriodicTaskExecuter.java
@@ -61,10 +61,29 @@ public class PeriodicTaskExecuter {
* Restores the manager.
*/
public void restore() {
- if ((isTimeFrequency()) && (timerExecuter != null)) {
- timerExecuter.scheduleTask(taskFrequency * 60000);
+ // TODO: Decouple service from this class once and forever.
+ if (!service.isRecording()) {
+ return;
+ }
+
+ if (!isTimeFrequency()) {
+ if (timerExecuter != null) {
+ timerExecuter.shutdown();
+ timerExecuter = null;
+ }
+ }
+ if (taskFrequency == 0) {
+ return;
+ }
+ if (isTimeFrequency()) {
+ if (timerExecuter == null) {
+ timerExecuter = new TimerTaskExecuter(task, service);
+ }
+ timerExecuter.scheduleTask(taskFrequency * 60000);
+ } else {
+ // For distance based splits.
+ calculateNextTaskDistance();
}
- calculateNextTaskDistance();
}
/**
@@ -140,30 +159,7 @@ public class PeriodicTaskExecuter {
public void setTaskFrequency(int taskFrequency) {
Log.d(TAG, "setTaskFrequency: taskFrequency = " + taskFrequency);
this.taskFrequency = taskFrequency;
-
- // TODO: Decouple service from this class once and forever.
- if (!service.isRecording()) {
- return;
- }
-
- if (!isTimeFrequency()) {
- if (timerExecuter != null) {
- timerExecuter.shutdown();
- timerExecuter = null;
- }
- }
- if (taskFrequency == 0) {
- return;
- }
- if (isTimeFrequency()) {
- if (timerExecuter == null) {
- timerExecuter = new TimerTaskExecuter(task, service);
- }
- timerExecuter.scheduleTask(taskFrequency * 60000);
- } else {
- // For distance based splits.
- calculateNextTaskDistance();
- }
+ restore();
}
public void setMetricUnits(boolean metricUnits) {
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/TimeSplitTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/SplitTask.java
similarity index 95%
rename from MyTracks/src/com/google/android/apps/mytracks/services/tasks/TimeSplitTask.java
rename to MyTracks/src/com/google/android/apps/mytracks/services/tasks/SplitTask.java
index 2b3f52a26..2a50f57fb 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/TimeSplitTask.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/SplitTask.java
@@ -24,7 +24,7 @@ import com.google.android.apps.mytracks.services.TrackRecordingService;
* A simple task to insert statistics markers every n minutes.
* @author Sandor Dornbush
*/
-public class TimeSplitTask implements PeriodicTask {
+public class SplitTask implements PeriodicTask {
@Override
public void run(TrackRecordingService service) {
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java
index 20e7178b2..f709db770 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTask.java
@@ -19,7 +19,6 @@ package com.google.android.apps.mytracks.services.tasks;
import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.Constants;
-import com.google.android.apps.mytracks.MyTracksSettings;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.StringUtils;
@@ -177,7 +176,7 @@ public class StatusAnnouncerTask implements PeriodicTask {
// @VisibleForTesting
protected String getAnnouncement(TripStatistics stats) {
SharedPreferences preferences =
- context.getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
+ context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
boolean metricUnits = true;
boolean reportSpeed = true;
if (preferences != null) {
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactoryTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactoryTest.java
similarity index 97%
rename from MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactoryTest.java
rename to MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactoryTest.java
index 154031126..70b649898 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerFactoryTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerFactoryTest.java
@@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package com.google.android.apps.mytracks.services;
+package com.google.android.apps.mytracks.services.tasks;
import com.google.android.apps.mytracks.services.tasks.PeriodicTask;
import com.google.android.apps.mytracks.services.tasks.StatusAnnouncerFactory;
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerTaskTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java
similarity index 99%
rename from MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerTaskTest.java
rename to MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java
index 9b94201f4..5d0bc0c87 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/services/StatusAnnouncerTaskTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/tasks/StatusAnnouncerTaskTest.java
@@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package com.google.android.apps.mytracks.services;
+package com.google.android.apps.mytracks.services.tasks;
import static com.google.android.testing.mocking.AndroidMock.capture;
import static com.google.android.testing.mocking.AndroidMock.eq;