forked from upstream-mirrors/OpenTracks
Add methods to TrackRecordingService to start and stop GPS.
No longer unregister location listener before registering it.
This commit is contained in:
+102
-56
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.services;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.TrackDetailActivity;
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProvider;
|
||||
@@ -44,7 +45,6 @@ import com.google.android.gms.location.LocationListener;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
@@ -88,7 +88,7 @@ public class TrackRecordingService extends Service {
|
||||
*/
|
||||
public static final String
|
||||
RESUME_TRACK_EXTRA_NAME = "com.google.android.apps.mytracks.RESUME_TRACK";
|
||||
|
||||
|
||||
public static final double PAUSE_LATITUDE = 100.0;
|
||||
public static final double RESUME_LATITUDE = 200.0;
|
||||
|
||||
@@ -286,7 +286,7 @@ public class TrackRecordingService extends Service {
|
||||
Log.w(TAG, "track is null, but recordingTrackId not -1L. " + recordingTrackId);
|
||||
updateRecordingState(PreferencesUtils.RECORDING_TRACK_ID_DEFAULT, true);
|
||||
}
|
||||
showNotification();
|
||||
showNotification(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ public class TrackRecordingService extends Service {
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
showNotification();
|
||||
showNotification(false);
|
||||
|
||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
checkLocationListener.cancel();
|
||||
@@ -403,7 +403,7 @@ public class TrackRecordingService extends Service {
|
||||
|
||||
WaypointType waypointType = waypointCreationRequest.getType();
|
||||
boolean isStatistics = waypointType == WaypointType.STATISTICS;
|
||||
|
||||
|
||||
// Get name
|
||||
String name;
|
||||
if (waypointCreationRequest.getName() != null) {
|
||||
@@ -423,7 +423,7 @@ public class TrackRecordingService extends Service {
|
||||
String category = waypointCreationRequest.getCategory() != null ? waypointCreationRequest
|
||||
.getCategory()
|
||||
: "";
|
||||
|
||||
|
||||
// Get tripStatistics, description, and icon
|
||||
TripStatistics tripStatistics;
|
||||
String description;
|
||||
@@ -462,10 +462,10 @@ public class TrackRecordingService extends Service {
|
||||
length = 0.0;
|
||||
duration = 0L;
|
||||
}
|
||||
|
||||
|
||||
// Insert waypoint
|
||||
Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, waypointType,
|
||||
length, duration, -1L, -1L, location, tripStatistics);
|
||||
Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId,
|
||||
waypointType, length, duration, -1L, -1L, location, tripStatistics);
|
||||
Uri uri = myTracksProviderUtils.insertWaypoint(waypoint);
|
||||
return Long.parseLong(uri.getLastPathSegment());
|
||||
}
|
||||
@@ -473,11 +473,16 @@ public class TrackRecordingService extends Service {
|
||||
/**
|
||||
* Starts the service as a foreground service.
|
||||
*
|
||||
* @param notification the notification for the foreground service
|
||||
* @param pendingIntent the notification pending intent
|
||||
* @param messageId the notification message id
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected void startForegroundService(Notification notification) {
|
||||
startForeground(1, notification);
|
||||
protected void startForegroundService(PendingIntent pendingIntent, int messageId) {
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setContentIntent(
|
||||
pendingIntent).setContentText(getString(messageId))
|
||||
.setContentTitle(getString(R.string.my_tracks_app_name)).setOngoing(true)
|
||||
.setSmallIcon(R.drawable.my_tracks_notification_icon).setWhen(System.currentTimeMillis());
|
||||
startForeground(1, builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -567,7 +572,7 @@ public class TrackRecordingService extends Service {
|
||||
// Update database
|
||||
track.setId(trackId);
|
||||
track.setName(TrackNameUtils.getTrackName(this, trackId, now, null));
|
||||
|
||||
|
||||
String category = PreferencesUtils.getString(
|
||||
this, R.string.default_activity_key, PreferencesUtils.DEFAULT_ACTIVITY_DEFAULT);
|
||||
track.setCategory(category);
|
||||
@@ -592,7 +597,8 @@ public class TrackRecordingService extends Service {
|
||||
trackTripStatisticsUpdater = new TripStatisticsUpdater(tripStatistics.getStartTime());
|
||||
|
||||
long markerStartTime;
|
||||
Waypoint waypoint = myTracksProviderUtils.getLastWaypoint(recordingTrackId, WaypointType.STATISTICS);
|
||||
Waypoint waypoint = myTracksProviderUtils.getLastWaypoint(
|
||||
recordingTrackId, WaypointType.STATISTICS);
|
||||
if (waypoint != null && waypoint.getTripStatistics() != null) {
|
||||
markerStartTime = waypoint.getTripStatistics().getStopTime();
|
||||
} else {
|
||||
@@ -661,18 +667,13 @@ public class TrackRecordingService extends Service {
|
||||
* @param trackStarted true if track is started, false if track is resumed
|
||||
*/
|
||||
private void startRecording(boolean trackStarted) {
|
||||
acquireWakeLock();
|
||||
|
||||
// Update instance variables
|
||||
sensorManager = SensorManagerFactory.getSystemSensorManager(this);
|
||||
lastLocation = null;
|
||||
currentSegmentHasLocation = false;
|
||||
|
||||
// Register notifications
|
||||
registerLocationListener();
|
||||
|
||||
// Send notifications
|
||||
showNotification();
|
||||
startGps();
|
||||
sendTrackBroadcast(trackStarted ? R.string.track_started_broadcast_action
|
||||
: R.string.track_resumed_broadcast_action, recordingTrackId);
|
||||
|
||||
@@ -681,6 +682,15 @@ public class TrackRecordingService extends Service {
|
||||
splitExecutor.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts gps.
|
||||
*/
|
||||
private void startGps() {
|
||||
acquireWakeLock();
|
||||
registerLocationListener();
|
||||
showNotification(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the current track.
|
||||
*/
|
||||
@@ -705,19 +715,6 @@ public class TrackRecordingService extends Service {
|
||||
}
|
||||
|
||||
endRecording(true, trackId);
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last valid track point in the current segment. Returns null if not available.
|
||||
*
|
||||
* @param trackId the track id
|
||||
*/
|
||||
private Location getLastValidTrackPointInCurrentSegment(long trackId) {
|
||||
if (!currentSegmentHasLocation) {
|
||||
return null;
|
||||
}
|
||||
return myTracksProviderUtils.getLastValidTrackPoint(trackId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -767,15 +764,36 @@ public class TrackRecordingService extends Service {
|
||||
}
|
||||
lastLocation = null;
|
||||
|
||||
// Unregister notifications
|
||||
unregisterLocationListener();
|
||||
|
||||
// Send notifications
|
||||
showNotification();
|
||||
sendTrackBroadcast(trackStopped ? R.string.track_stopped_broadcast_action
|
||||
: R.string.track_paused_broadcast_action, trackId);
|
||||
stopGps(trackStopped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops gps.
|
||||
*
|
||||
* @param stop true to stop self
|
||||
*/
|
||||
private void stopGps(boolean stop) {
|
||||
unregisterLocationListener();
|
||||
showNotification(false);
|
||||
releaseWakeLock();
|
||||
if (stop) {
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last valid track point in the current segment. Returns null if not
|
||||
* available.
|
||||
*
|
||||
* @param trackId the track id
|
||||
*/
|
||||
private Location getLastValidTrackPointInCurrentSegment(long trackId) {
|
||||
if (!currentSegmentHasLocation) {
|
||||
return null;
|
||||
}
|
||||
return myTracksProviderUtils.getLastValidTrackPoint(trackId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -818,7 +836,7 @@ public class TrackRecordingService extends Service {
|
||||
Log.d(TAG, "Ignore onLocationChangedAsync. Poor accuracy.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Fix for phones that do not set the time field
|
||||
if (location.getTime() == 0L) {
|
||||
location.setTime(System.currentTimeMillis());
|
||||
@@ -828,7 +846,7 @@ public class TrackRecordingService extends Service {
|
||||
long idleTime = 0L;
|
||||
if (lastValidTrackPoint != null && location.getTime() > lastValidTrackPoint.getTime()) {
|
||||
idleTime = location.getTime() - lastValidTrackPoint.getTime();
|
||||
}
|
||||
}
|
||||
locationListenerPolicy.updateIdleTime(idleTime);
|
||||
if (currentRecordingInterval != locationListenerPolicy.getDesiredPollingInterval()) {
|
||||
registerLocationListener();
|
||||
@@ -900,7 +918,7 @@ public class TrackRecordingService extends Service {
|
||||
return;
|
||||
}
|
||||
// Do not insert if inserted already
|
||||
if (lastValidTrackPoint != null && lastValidTrackPoint.getTime() == location.getTime()) {
|
||||
if (lastValidTrackPoint != null && lastValidTrackPoint.getTime() == location.getTime()) {
|
||||
Log.w(TAG, "Ignore insertLocation. location time same as last valid track point time.");
|
||||
return;
|
||||
}
|
||||
@@ -959,8 +977,6 @@ public class TrackRecordingService extends Service {
|
||||
*/
|
||||
handler.post(new Runnable() {
|
||||
public void run() {
|
||||
unregisterLocationListener();
|
||||
|
||||
if (myTracksLocationManager == null) {
|
||||
Log.e(TAG, "locationManager is null.");
|
||||
return;
|
||||
@@ -1028,21 +1044,32 @@ public class TrackRecordingService extends Service {
|
||||
|
||||
/**
|
||||
* Shows the notification.
|
||||
*
|
||||
* @param isGpsStarted true if GPS is started
|
||||
*/
|
||||
private void showNotification() {
|
||||
if (isRecording() && !isPaused()) {
|
||||
Intent intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
|
||||
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, recordingTrackId);
|
||||
PendingIntent pendingIntent = TaskStackBuilder.create(this)
|
||||
.addParentStack(TrackDetailActivity.class).addNextIntent(intent)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this).setContentIntent(
|
||||
pendingIntent).setContentText(getString(R.string.track_record_notification))
|
||||
.setContentTitle(getString(R.string.my_tracks_app_name)).setOngoing(true)
|
||||
.setSmallIcon(R.drawable.my_tracks_notification_icon).setWhen(System.currentTimeMillis());
|
||||
startForegroundService(builder.build());
|
||||
private void showNotification(boolean isGpsStarted) {
|
||||
if (isRecording()) {
|
||||
if (isPaused()) {
|
||||
stopForegroundService();
|
||||
} else {
|
||||
Intent intent = IntentUtils.newIntent(this, TrackDetailActivity.class)
|
||||
.putExtra(TrackDetailActivity.EXTRA_TRACK_ID, recordingTrackId);
|
||||
PendingIntent pendingIntent = TaskStackBuilder.create(this)
|
||||
.addParentStack(TrackDetailActivity.class).addNextIntent(intent)
|
||||
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
startForegroundService(pendingIntent, R.string.track_record_notification);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
stopForegroundService();
|
||||
// Not recording
|
||||
if (isGpsStarted) {
|
||||
Intent intent = IntentUtils.newIntent(this, TrackListActivity.class);
|
||||
PendingIntent pendingIntent = TaskStackBuilder.create(this)
|
||||
.addNextIntent(intent).getPendingIntent(0, 0);
|
||||
startForegroundService(pendingIntent, R.string.gps_starting);
|
||||
} else {
|
||||
stopForegroundService();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,6 +1130,25 @@ public class TrackRecordingService extends Service {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startGps() {
|
||||
if (!canAccess()) {
|
||||
return;
|
||||
}
|
||||
if (!trackRecordingService.isRecording()) {
|
||||
trackRecordingService.startGps();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopGps() {
|
||||
if (!canAccess()) {
|
||||
return;
|
||||
}
|
||||
if (!trackRecordingService.isRecording()) {
|
||||
trackRecordingService.stopGps(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long startNewTrack() {
|
||||
if (!canAccess()) {
|
||||
|
||||
+12
-2
@@ -23,6 +23,16 @@ import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
*/
|
||||
interface ITrackRecordingService {
|
||||
|
||||
/**
|
||||
* Starts gps.
|
||||
*/
|
||||
void startGps();
|
||||
|
||||
/**
|
||||
* Stops gps.
|
||||
*/
|
||||
void stopGps();
|
||||
|
||||
/**
|
||||
* Starts recording a new track.
|
||||
*
|
||||
@@ -85,14 +95,14 @@ interface ITrackRecordingService {
|
||||
|
||||
/**
|
||||
* Gets the current sensor data. Returns null if there is no data.
|
||||
|
||||
|
||||
* @return a byte array of the binary version of the Sensor.SensorDataSet object.
|
||||
*/
|
||||
byte[] getSensorData();
|
||||
|
||||
/**
|
||||
* Gets the current sensor manager state.
|
||||
*
|
||||
*
|
||||
* return a Sensor.SensorState enum value.
|
||||
*/
|
||||
int getSensorState();
|
||||
|
||||
+7
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
package com.google.android.apps.mytracks.services;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.test.ServiceTestCase;
|
||||
import android.util.Log;
|
||||
@@ -11,15 +11,16 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* A {@link TrackRecordingService} that can be used with {@link ServiceTestCase}.
|
||||
* {@link ServiceTestCase} throws a null pointer exception when the service
|
||||
* calls {@link Service#startForeground(int, android.app.Notification)} and
|
||||
* A {@link TrackRecordingService} that can be used with
|
||||
* {@link ServiceTestCase}. {@link ServiceTestCase} throws a null pointer
|
||||
* exception when the service calls
|
||||
* {@link Service#startForeground(int, android.app.Notification)} and
|
||||
* {@link Service#stopForeground(boolean)}.
|
||||
* <p>
|
||||
* See http://code.google.com/p/android/issues/detail?id=12122
|
||||
* <p>
|
||||
* Wrap these two methods in wrappers and override them.
|
||||
*
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class TestRecordingService extends TrackRecordingService {
|
||||
@@ -27,7 +28,7 @@ public class TestRecordingService extends TrackRecordingService {
|
||||
private static final String TAG = TestRecordingService.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
protected void startForegroundService(Notification notification) {
|
||||
protected void startForegroundService(PendingIntent pendingIntent, int messageId) {
|
||||
try {
|
||||
Method setForegroundMethod = Service.class.getMethod("setForeground", boolean.class);
|
||||
setForegroundMethod.invoke(this, true);
|
||||
|
||||
Reference in New Issue
Block a user