forked from upstream-mirrors/OpenTracks
323 lines
8.8 KiB
Java
323 lines
8.8 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 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.content.Context;
|
|
import android.content.SharedPreferences;
|
|
import android.location.Location;
|
|
import android.os.Bundle;
|
|
import android.support.v4.app.Fragment;
|
|
import android.util.Log;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.ScrollView;
|
|
|
|
import java.util.EnumSet;
|
|
|
|
/**
|
|
* A fragment to display track statistics to the user.
|
|
*
|
|
* @author Sandor Dornbush
|
|
* @author Rodrigo Damazio
|
|
*/
|
|
public class StatsFragment extends Fragment implements TrackDataListener {
|
|
|
|
private static final String TAG = StatsFragment.class.getSimpleName();
|
|
|
|
private SharedPreferences sharedPreferences;
|
|
private StatsUtilities statsUtilities;
|
|
private TrackDataHub trackDataHub;
|
|
private UiUpdateThread uiUpdateThread;
|
|
|
|
// The start time of the current track.
|
|
private long startTime = -1L;
|
|
|
|
// A runnable to update the total time field.
|
|
private final Runnable updateTotalTime = new Runnable() {
|
|
public void run() {
|
|
if (isRecording()) {
|
|
statsUtilities.setTime(R.id.total_time_register, System.currentTimeMillis() - startTime);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* A thread that updates the total time field every second.
|
|
*/
|
|
private class UiUpdateThread extends Thread {
|
|
|
|
@Override
|
|
public void run() {
|
|
Log.d(TAG, "UI update thread started");
|
|
while (ServiceUtils.isRecording(getActivity(), null, sharedPreferences)) {
|
|
getActivity().runOnUiThread(updateTotalTime);
|
|
try {
|
|
Thread.sleep(1000L);
|
|
} catch (InterruptedException e) {
|
|
Log.d(TAG, "UI update thread caught exception", e);
|
|
break;
|
|
}
|
|
}
|
|
Log.d(TAG, "UI update thread finished");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
sharedPreferences = getActivity()
|
|
.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
|
statsUtilities = new StatsUtilities(getActivity());
|
|
}
|
|
|
|
@Override
|
|
public View onCreateView(
|
|
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
|
return inflater.inflate(R.layout.stats, container, false);
|
|
}
|
|
|
|
@Override
|
|
public void onActivityCreated(Bundle savedInstanceState) {
|
|
super.onActivityCreated(savedInstanceState);
|
|
ScrollView scrollView = (ScrollView) getActivity().findViewById(R.id.scrolly);
|
|
scrollView.setScrollBarStyle(ScrollView.SCROLLBARS_OUTSIDE_INSET);
|
|
updateLabels();
|
|
setLocationUnknown();
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
resumeTrackDataHub();
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
super.onPause();
|
|
pauseTrackDataHub();
|
|
if (uiUpdateThread != null) {
|
|
uiUpdateThread.interrupt();
|
|
uiUpdateThread = null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onProviderStateChange(ProviderState state) {
|
|
if (state == ProviderState.DISABLED || state == ProviderState.NO_FIX) {
|
|
getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
setLocationUnknown();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCurrentLocationChanged(final Location location) {
|
|
if (isRecording()) {
|
|
getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (location != null) {
|
|
setLocation(location);
|
|
} else {
|
|
setLocationUnknown();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCurrentHeadingChanged(double heading) {
|
|
// We don't care.
|
|
}
|
|
|
|
@Override
|
|
public void onSelectedTrackChanged(Track track, boolean isRecording) {
|
|
if (uiUpdateThread == null && isRecording) {
|
|
uiUpdateThread = new UiUpdateThread();
|
|
uiUpdateThread.start();
|
|
} else if (uiUpdateThread != null && !isRecording) {
|
|
uiUpdateThread.interrupt();
|
|
uiUpdateThread = null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onTrackUpdated(final Track track) {
|
|
getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (track == null || track.getStatistics() == null) {
|
|
statsUtilities.setAllToUnknown();
|
|
return;
|
|
}
|
|
|
|
startTime = track.getStatistics().getStartTime();
|
|
if (!isRecording()) {
|
|
statsUtilities.setTime(R.id.total_time_register, track.getStatistics().getTotalTime());
|
|
setLocationUnknown();
|
|
}
|
|
statsUtilities.setAllStats(track.getStatistics());
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void clearTrackPoints() {
|
|
// We don't care.
|
|
}
|
|
|
|
@Override
|
|
public void onNewTrackPoint(Location loc) {
|
|
// We don't care.
|
|
}
|
|
|
|
@Override
|
|
public void onSampledOutTrackPoint(Location loc) {
|
|
// We don't care.
|
|
}
|
|
|
|
@Override
|
|
public void onSegmentSplit() {
|
|
// We don't care.
|
|
}
|
|
|
|
@Override
|
|
public void onNewTrackPointsDone() {
|
|
// We don't care.
|
|
}
|
|
|
|
@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 boolean onUnitsChanged(boolean metric) {
|
|
if (statsUtilities.isMetricUnits() == metric) {
|
|
return false;
|
|
}
|
|
statsUtilities.setMetricUnits(metric);
|
|
getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
updateLabels();
|
|
}
|
|
});
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onReportSpeedChanged(boolean speed) {
|
|
if (statsUtilities.isReportSpeed() == speed) {
|
|
return false;
|
|
}
|
|
statsUtilities.setReportSpeed(speed);
|
|
getActivity().runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
updateLabels();
|
|
}
|
|
});
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Resumes the trackDataHub. Needs to be synchronized because trackDataHub can
|
|
* be accessed by multiple threads.
|
|
*/
|
|
private synchronized void resumeTrackDataHub() {
|
|
trackDataHub = ((MyTracksApplication) getActivity().getApplication()).getTrackDataHub();
|
|
trackDataHub.registerTrackDataListener(this, EnumSet.of(
|
|
ListenerDataType.SELECTED_TRACK_CHANGED,
|
|
ListenerDataType.TRACK_UPDATES,
|
|
ListenerDataType.LOCATION_UPDATES,
|
|
ListenerDataType.DISPLAY_PREFERENCES));
|
|
}
|
|
|
|
/**
|
|
* Pauses the trackDataHub. Needs to be synchronized because trackDataHub can
|
|
* be accessed by multiple threads.
|
|
*/
|
|
private synchronized void pauseTrackDataHub() {
|
|
trackDataHub.unregisterTrackDataListener(this);
|
|
trackDataHub = null;
|
|
}
|
|
|
|
/**
|
|
* Returns true if recording. Needs to be synchronized because trackDataHub
|
|
* can be accessed by multiple threads.
|
|
*/
|
|
private synchronized boolean isRecording() {
|
|
return trackDataHub != null && trackDataHub.isRecordingSelected();
|
|
}
|
|
|
|
/**
|
|
* Updates the labels.
|
|
*/
|
|
private void updateLabels() {
|
|
statsUtilities.updateUnits();
|
|
statsUtilities.setSpeedLabel(R.id.speed_label, R.string.stat_speed, R.string.stat_pace);
|
|
statsUtilities.setSpeedLabels();
|
|
}
|
|
|
|
/**
|
|
* Sets the current location.
|
|
*
|
|
* @param location the current location
|
|
*/
|
|
private void setLocation(Location location) {
|
|
statsUtilities.setAltitude(R.id.elevation_register, location.getAltitude());
|
|
statsUtilities.setLatLong(R.id.latitude_register, location.getLatitude());
|
|
statsUtilities.setLatLong(R.id.longitude_register, location.getLongitude());
|
|
statsUtilities.setSpeed(R.id.speed_register, location.getSpeed() * UnitConversions.MS_TO_KMH);
|
|
}
|
|
|
|
/**
|
|
* Sets the current location to unknown.
|
|
*/
|
|
private void setLocationUnknown() {
|
|
statsUtilities.setUnknown(R.id.elevation_register);
|
|
statsUtilities.setUnknown(R.id.latitude_register);
|
|
statsUtilities.setUnknown(R.id.longitude_register);
|
|
statsUtilities.setUnknown(R.id.speed_register);
|
|
}
|
|
}
|