forked from upstream-mirrors/OpenTracks
Use handler directly instead of using a timer in TrackRecordingService
This commit is contained in:
@@ -65,7 +65,6 @@ import android.os.Binder;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.PowerManager.WakeLock;
|
import android.os.PowerManager.WakeLock;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
@@ -73,8 +72,6 @@ import android.support.v4.app.NotificationCompat;
|
|||||||
import android.support.v4.app.TaskStackBuilder;
|
import android.support.v4.app.TaskStackBuilder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
@@ -86,9 +83,6 @@ import java.util.concurrent.Executors;
|
|||||||
*/
|
*/
|
||||||
public class TrackRecordingService extends Service {
|
public class TrackRecordingService extends Service {
|
||||||
|
|
||||||
private static final String TAG = TrackRecordingService.class.getSimpleName();
|
|
||||||
private static final long ACTIVITY_RECOGNITION_INTERVAL = 60000; // 1 minute
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of extra intent property to indicate whether we want to resume a
|
* The name of extra intent property to indicate whether we want to resume a
|
||||||
* previously recorded track.
|
* previously recorded track.
|
||||||
@@ -99,22 +93,23 @@ public class TrackRecordingService extends Service {
|
|||||||
public static final double PAUSE_LATITUDE = 100.0;
|
public static final double PAUSE_LATITUDE = 100.0;
|
||||||
public static final double RESUME_LATITUDE = 200.0;
|
public static final double RESUME_LATITUDE = 200.0;
|
||||||
|
|
||||||
// One second in milliseconds
|
private static final String TAG = TrackRecordingService.class.getSimpleName();
|
||||||
private static final long ONE_SECOND = 1000;
|
private static final long ONE_SECOND = 1000; // in milliseconds
|
||||||
// One minute in milliseconds
|
private static final long ONE_MINUTE = 60 * ONE_SECOND; // in milliseconds
|
||||||
private static final long ONE_MINUTE = 60 * ONE_SECOND;
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final int MAX_AUTO_RESUME_TRACK_RETRY_ATTEMPTS = 3;
|
static final int MAX_AUTO_RESUME_TRACK_RETRY_ATTEMPTS = 3;
|
||||||
|
|
||||||
// The following variables are set in onCreate:
|
// The following variables are set in onCreate:
|
||||||
|
private ExecutorService executorService;
|
||||||
private Context context;
|
private Context context;
|
||||||
private MyTracksProviderUtils myTracksProviderUtils;
|
private MyTracksProviderUtils myTracksProviderUtils;
|
||||||
|
private Handler handler;
|
||||||
private MyTracksLocationManager myTracksLocationManager;
|
private MyTracksLocationManager myTracksLocationManager;
|
||||||
private ActivityRecognitionClient activityRecognitionClient;
|
|
||||||
private PendingIntent activityRecognitionPendingIntent;
|
private PendingIntent activityRecognitionPendingIntent;
|
||||||
|
private ActivityRecognitionClient activityRecognitionClient;
|
||||||
private PeriodicTaskExecutor voiceExecutor;
|
private PeriodicTaskExecutor voiceExecutor;
|
||||||
private PeriodicTaskExecutor splitExecutor;
|
private PeriodicTaskExecutor splitExecutor;
|
||||||
private ExecutorService executorService;
|
|
||||||
private SharedPreferences sharedPreferences;
|
private SharedPreferences sharedPreferences;
|
||||||
private long recordingTrackId;
|
private long recordingTrackId;
|
||||||
private boolean recordingTrackPaused;
|
private boolean recordingTrackPaused;
|
||||||
@@ -133,13 +128,6 @@ public class TrackRecordingService extends Service {
|
|||||||
private Location lastLocation;
|
private Location lastLocation;
|
||||||
private boolean currentSegmentHasLocation;
|
private boolean currentSegmentHasLocation;
|
||||||
|
|
||||||
// TimerTask to register location listener
|
|
||||||
private TimerTask timerTask;
|
|
||||||
private Timer timer;
|
|
||||||
|
|
||||||
// Handler for the timer to post a runnable to the main thread
|
|
||||||
private final Handler handler = new Handler();
|
|
||||||
|
|
||||||
private ServiceBinder binder = new ServiceBinder(this);
|
private ServiceBinder binder = new ServiceBinder(this);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -255,7 +243,7 @@ public class TrackRecordingService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onConnected(Bundle bundle) {
|
public void onConnected(Bundle bundle) {
|
||||||
activityRecognitionClient.requestActivityUpdates(
|
activityRecognitionClient.requestActivityUpdates(
|
||||||
ACTIVITY_RECOGNITION_INTERVAL, activityRecognitionPendingIntent);
|
ONE_MINUTE, activityRecognitionPendingIntent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -265,6 +253,17 @@ public class TrackRecordingService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onConnectionFailed(ConnectionResult connectionResult) {}
|
public void onConnectionFailed(ConnectionResult connectionResult) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final Runnable registerLocationRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (isRecording() && !isPaused()) {
|
||||||
|
registerLocationListener();
|
||||||
|
}
|
||||||
|
handler.postDelayed(this, ONE_MINUTE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that this service, through the AndroidManifest.xml, is configured to
|
* Note that this service, through the AndroidManifest.xml, is configured to
|
||||||
* allow both MyTracks and third party apps to invoke it. For the onCreate
|
* allow both MyTracks and third party apps to invoke it. For the onCreate
|
||||||
@@ -275,9 +274,11 @@ public class TrackRecordingService extends Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
executorService = Executors.newSingleThreadExecutor();
|
||||||
context = this;
|
context = this;
|
||||||
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
|
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
|
||||||
myTracksLocationManager = new MyTracksLocationManager(this, Looper.myLooper(), true);
|
handler = new Handler();
|
||||||
|
myTracksLocationManager = new MyTracksLocationManager(this, handler.getLooper(), true);
|
||||||
activityRecognitionPendingIntent = PendingIntent.getService(context, 0,
|
activityRecognitionPendingIntent = PendingIntent.getService(context, 0,
|
||||||
new Intent(context, ActivityRecognitionIntentService.class),
|
new Intent(context, ActivityRecognitionIntentService.class),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
@@ -286,7 +287,6 @@ public class TrackRecordingService extends Service {
|
|||||||
activityRecognitionClient.connect();
|
activityRecognitionClient.connect();
|
||||||
voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTaskFactory());
|
voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTaskFactory());
|
||||||
splitExecutor = new PeriodicTaskExecutor(this, new SplitPeriodicTaskFactory());
|
splitExecutor = new PeriodicTaskExecutor(this, new SplitPeriodicTaskFactory());
|
||||||
executorService = Executors.newSingleThreadExecutor();
|
|
||||||
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||||
|
|
||||||
@@ -296,16 +296,7 @@ public class TrackRecordingService extends Service {
|
|||||||
// Require voiceExecutor and splitExecutor to be created.
|
// Require voiceExecutor and splitExecutor to be created.
|
||||||
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, null);
|
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, null);
|
||||||
|
|
||||||
timerTask = new TimerTask() {
|
handler.post(registerLocationRunnable);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (isRecording() && !isPaused()) {
|
|
||||||
registerLocationListener();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
timer = new Timer("TrackRecordingServiceTimer");
|
|
||||||
timer.schedule(timerTask, 0, ONE_MINUTE);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to restart the previous recording track in case the service has been
|
* Try to restart the previous recording track in case the service has been
|
||||||
@@ -355,25 +346,19 @@ public class TrackRecordingService extends Service {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
|
if (sensorManager != null) {
|
||||||
|
SensorManagerFactory.releaseSystemSensorManager();
|
||||||
|
sensorManager = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse order from onCreate
|
||||||
showNotification(false);
|
showNotification(false);
|
||||||
|
|
||||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
handler.removeCallbacks(registerLocationRunnable);
|
||||||
if (timerTask != null) {
|
|
||||||
timerTask.cancel();
|
|
||||||
timerTask = null;
|
|
||||||
}
|
|
||||||
if (timer != null) {
|
|
||||||
timer.cancel();
|
|
||||||
timer.purge();
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
unregisterLocationListener();
|
unregisterLocationListener();
|
||||||
|
|
||||||
try {
|
// unregister sharedPreferences before shutting down splitExecutor and voiceExecutor
|
||||||
voiceExecutor.shutdown();
|
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||||
} finally {
|
|
||||||
voiceExecutor = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
splitExecutor.shutdown();
|
splitExecutor.shutdown();
|
||||||
@@ -381,22 +366,22 @@ public class TrackRecordingService extends Service {
|
|||||||
splitExecutor = null;
|
splitExecutor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sensorManager != null) {
|
try {
|
||||||
SensorManagerFactory.releaseSystemSensorManager();
|
voiceExecutor.shutdown();
|
||||||
sensorManager = null;
|
} finally {
|
||||||
|
voiceExecutor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we have no indirect references to this service.
|
|
||||||
myTracksProviderUtils = null;
|
|
||||||
myTracksLocationManager.close();
|
|
||||||
myTracksLocationManager = null;
|
|
||||||
|
|
||||||
if (activityRecognitionClient.isConnected()) {
|
if (activityRecognitionClient.isConnected()) {
|
||||||
activityRecognitionClient.removeActivityUpdates(activityRecognitionPendingIntent);
|
activityRecognitionClient.removeActivityUpdates(activityRecognitionPendingIntent);
|
||||||
}
|
}
|
||||||
activityRecognitionClient.disconnect();
|
activityRecognitionClient.disconnect();
|
||||||
activityRecognitionPendingIntent.cancel();
|
activityRecognitionPendingIntent.cancel();
|
||||||
|
|
||||||
|
myTracksLocationManager.close();
|
||||||
|
myTracksLocationManager = null;
|
||||||
|
myTracksProviderUtils = null;
|
||||||
|
|
||||||
binder.detachFromService();
|
binder.detachFromService();
|
||||||
binder = null;
|
binder = null;
|
||||||
|
|
||||||
@@ -404,7 +389,7 @@ public class TrackRecordingService extends Service {
|
|||||||
releaseWakeLock();
|
releaseWakeLock();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shutdown the executor service last to avoid sending events to a dead
|
* Shutdown the executorService last to avoid sending events to a dead
|
||||||
* executor.
|
* executor.
|
||||||
*/
|
*/
|
||||||
executorService.shutdown();
|
executorService.shutdown();
|
||||||
@@ -1042,26 +1027,18 @@ public class TrackRecordingService extends Service {
|
|||||||
* Registers the location listener.
|
* Registers the location listener.
|
||||||
*/
|
*/
|
||||||
private void registerLocationListener() {
|
private void registerLocationListener() {
|
||||||
/*
|
if (myTracksLocationManager == null) {
|
||||||
* Use the handler so the requestLocationUpdaets locationListener will be
|
Log.e(TAG, "locationManager is null.");
|
||||||
* invoked on the handler thread.
|
return;
|
||||||
*/
|
}
|
||||||
handler.post(new Runnable() {
|
try {
|
||||||
public void run() {
|
long interval = locationListenerPolicy.getDesiredPollingInterval();
|
||||||
if (myTracksLocationManager == null) {
|
myTracksLocationManager.requestLocationUpdates(
|
||||||
Log.e(TAG, "locationManager is null.");
|
interval, locationListenerPolicy.getMinDistance(), locationListener);
|
||||||
return;
|
currentRecordingInterval = interval;
|
||||||
}
|
} catch (RuntimeException e) {
|
||||||
try {
|
Log.e(TAG, "Could not register location listener.", e);
|
||||||
long interval = locationListenerPolicy.getDesiredPollingInterval();
|
}
|
||||||
myTracksLocationManager.requestLocationUpdates(
|
|
||||||
interval, locationListenerPolicy.getMinDistance(), locationListener);
|
|
||||||
currentRecordingInterval = interval;
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
Log.e(TAG, "Could not register location listener.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user