forked from upstream-mirrors/OpenTracks
321 lines
8.6 KiB
Java
321 lines
8.6 KiB
Java
/*
|
|
* Copyright 2008 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
* use this file except in compliance with the License. You may obtain a copy of
|
|
* the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations under
|
|
* the License.
|
|
*/
|
|
package com.google.android.apps.mytracks;
|
|
|
|
import static com.google.android.apps.mytracks.Constants.TAG;
|
|
|
|
import com.google.android.apps.mytracks.content.Track;
|
|
import com.google.android.apps.mytracks.content.TrackDataHub;
|
|
import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
|
|
import com.google.android.apps.mytracks.content.TrackDataListener;
|
|
import com.google.android.apps.mytracks.content.Waypoint;
|
|
import com.google.android.apps.mytracks.services.ServiceUtils;
|
|
import com.google.android.apps.mytracks.util.UnitConversions;
|
|
import com.google.android.maps.mytracks.R;
|
|
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.SharedPreferences;
|
|
import android.location.Location;
|
|
import android.os.Bundle;
|
|
import android.speech.tts.TextToSpeech;
|
|
import android.util.DisplayMetrics;
|
|
import android.util.Log;
|
|
import android.widget.ScrollView;
|
|
import android.widget.TextView;
|
|
|
|
import java.util.EnumSet;
|
|
|
|
/**
|
|
* An activity that displays track statistics to the user.
|
|
*
|
|
* @author Sandor Dornbush
|
|
* @author Rodrigo Damazio
|
|
*/
|
|
public class StatsActivity extends Activity implements TrackDataListener {
|
|
/**
|
|
* A runnable for posting to the UI thread. Will update the total time field.
|
|
*/
|
|
private final Runnable updateResults = new Runnable() {
|
|
public void run() {
|
|
if (dataHub != null && dataHub.isRecordingSelected()) {
|
|
utils.setTime(R.id.total_time_register,
|
|
System.currentTimeMillis() - startTime);
|
|
}
|
|
}
|
|
};
|
|
|
|
private StatsUtilities utils;
|
|
private UIUpdateThread thread;
|
|
|
|
/**
|
|
* The start time of the selected track.
|
|
*/
|
|
private long startTime = -1;
|
|
|
|
private TrackDataHub dataHub;
|
|
private SharedPreferences preferences;
|
|
|
|
/**
|
|
* A thread that updates the total time field every second.
|
|
*/
|
|
private class UIUpdateThread extends Thread {
|
|
|
|
public UIUpdateThread() {
|
|
super();
|
|
Log.i(TAG, "Created UI update thread");
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
Log.i(TAG, "Started UI update thread");
|
|
while (ServiceUtils.isRecording(StatsActivity.this, null, preferences)) {
|
|
runOnUiThread(updateResults);
|
|
try {
|
|
Thread.sleep(1000L);
|
|
} catch (InterruptedException e) {
|
|
Log.w(TAG, "StatsActivity: Caught exception on sleep.", e);
|
|
break;
|
|
}
|
|
}
|
|
Log.w(TAG, "UIUpdateThread finished.");
|
|
}
|
|
}
|
|
|
|
/** Called when the activity is first created. */
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
|
|
preferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
|
utils = new StatsUtilities(this);
|
|
|
|
// The volume we want to control is the Text-To-Speech volume
|
|
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
|
|
|
|
setContentView(R.layout.stats);
|
|
|
|
ScrollView sv = ((ScrollView) findViewById(R.id.scrolly));
|
|
sv.setScrollBarStyle(ScrollView.SCROLLBARS_OUTSIDE_INSET);
|
|
|
|
showUnknownLocation();
|
|
updateLabels();
|
|
|
|
DisplayMetrics metrics = new DisplayMetrics();
|
|
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
|
if (metrics.heightPixels > 600) {
|
|
((TextView) findViewById(R.id.speed_register)).setTextSize(80.0f);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onResume() {
|
|
super.onResume();
|
|
|
|
dataHub = ((MyTracksApplication) getApplication()).getTrackDataHub();
|
|
dataHub.registerTrackDataListener(this, EnumSet.of(
|
|
ListenerDataType.SELECTED_TRACK_CHANGED,
|
|
ListenerDataType.TRACK_UPDATES,
|
|
ListenerDataType.LOCATION_UPDATES,
|
|
ListenerDataType.DISPLAY_PREFERENCES));
|
|
}
|
|
|
|
@Override
|
|
protected void onPause() {
|
|
dataHub.unregisterTrackDataListener(this);
|
|
dataHub = null;
|
|
|
|
if (thread != null) {
|
|
thread.interrupt();
|
|
thread = null;
|
|
}
|
|
|
|
super.onStop();
|
|
}
|
|
|
|
@Override
|
|
public boolean onUnitsChanged(boolean metric) {
|
|
if (utils.isMetricUnits() == metric) {
|
|
return false;
|
|
}
|
|
utils.setMetricUnits(metric);
|
|
updateLabels();
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onReportSpeedChanged(boolean speed) {
|
|
if (utils.isReportSpeed() == speed) {
|
|
return false;
|
|
}
|
|
utils.setReportSpeed(speed);
|
|
updateLabels();
|
|
return true;
|
|
}
|
|
|
|
private void updateLabels() {
|
|
runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
utils.updateUnits();
|
|
utils.setSpeedLabel(R.id.speed_label, R.string.stat_speed, R.string.stat_pace);
|
|
utils.setSpeedLabels();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Updates the given location fields (latitude, longitude, altitude) and all
|
|
* other fields.
|
|
*
|
|
* @param l may be null (will set location fields to unknown)
|
|
*/
|
|
private void showLocation(Location l) {
|
|
utils.setAltitude(R.id.elevation_register, l.getAltitude());
|
|
utils.setLatLong(R.id.latitude_register, l.getLatitude());
|
|
utils.setLatLong(R.id.longitude_register, l.getLongitude());
|
|
utils.setSpeed(R.id.speed_register, l.getSpeed() * UnitConversions.MS_TO_KMH);
|
|
}
|
|
|
|
private void showUnknownLocation() {
|
|
utils.setUnknown(R.id.elevation_register);
|
|
utils.setUnknown(R.id.latitude_register);
|
|
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;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCurrentLocationChanged(final Location loc) {
|
|
TrackDataHub localDataHub = dataHub;
|
|
if (localDataHub != null && localDataHub.isRecordingSelected()) {
|
|
runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (loc != null) {
|
|
showLocation(loc);
|
|
} else {
|
|
showUnknownLocation();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCurrentHeadingChanged(double heading) {
|
|
// We don't care.
|
|
}
|
|
|
|
@Override
|
|
public void onProviderStateChange(ProviderState state) {
|
|
switch (state) {
|
|
case DISABLED:
|
|
case NO_FIX:
|
|
runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
showUnknownLocation();
|
|
}
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onTrackUpdated(final Track track) {
|
|
TrackDataHub localDataHub = dataHub;
|
|
final boolean recordingSelected = localDataHub != null && localDataHub.isRecordingSelected();
|
|
runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (track == null || track.getStatistics() == null) {
|
|
utils.setAllToUnknown();
|
|
return;
|
|
}
|
|
|
|
startTime = track.getStatistics().getStartTime();
|
|
if (!recordingSelected) {
|
|
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.
|
|
}
|
|
}
|