Compare commits

...

10 Commits

Author SHA1 Message Date
Dennis Guse 8d7a8719bc Release: v4.9.9 2023-12-27 10:32:39 +01:00
Dennis Guse 8f5388edce While recording: show BLE sensor name instead of address.
Fixes #1796.
2023-12-26 11:22:05 +01:00
Dennis Guse 81a78820cc Merge pull request #1793 from OpenTracksApp/crash#1708
Bugfix: sensors were started twice.
2023-12-26 09:04:29 +01:00
Dennis Guse 2fe452c77c Revert "fix NPE at null barometer after unregister listener"
This reverts commit 5dbd17f3bb.
2023-12-26 08:42:38 +01:00
Dennis Guse 826cf0d468 Bugfix: TrackListActivity couldn't stop and restart sensors.
Part of #1780.
2023-12-26 08:42:38 +01:00
Dennis Guse 6cd627e832 Bugfix: TrackRecordingService can only start sensors once.
Fixes #1780.
2023-12-26 08:42:37 +01:00
Dennis Guse 0ee4a4e72f Bugfix: TrackListActivity triggered TrackRecordingService twice (startSensors and startRecording).
Part of #1780.
2023-12-25 20:49:49 +01:00
Dennis Guse 150cbee95b BarometerInternal: if there is no internal barometer - don't register a listener. 2023-12-25 18:48:14 +01:00
Dennis Guse 47ceb297c9 SensorManager: crash if started twice.
Part of #1780.
2023-12-24 22:10:58 +01:00
Dennis Guse aed4af5736 Bluetooth logs: make them slightly more readable. 2023-12-24 21:49:48 +01:00
21 changed files with 95 additions and 86 deletions
+2 -2
View File
@@ -64,8 +64,8 @@ android {
defaultConfig { defaultConfig {
applicationId "de.dennisguse.opentracks" applicationId "de.dennisguse.opentracks"
versionCode 5563 versionCode 5573
versionName "v4.9.8" versionName "v4.9.9"
buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\"" buildConfigField "String", "VERSION_NAME_FULL", "\"${getVersionName()}\""
@@ -0,0 +1,6 @@
v4.9.9: OpenTracks
Bugfix:
- Crash when using a BLE sensor on recording end (race condition)
Reason: sensor subsystem was started twice and only the 2nd one was shutdown.
- While recording, BLE sensor names are shown again
@@ -25,6 +25,7 @@ import android.graphics.drawable.AnimatedVectorDrawable;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@@ -73,7 +74,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
private static final String TAG = TrackListActivity.class.getSimpleName(); private static final String TAG = TrackListActivity.class.getSimpleName();
// The following are set in onCreate // The following are set in onCreate
private TrackRecordingServiceConnection trackRecordingServiceConnection; private TrackRecordingServiceConnection recordingStatusConnection;
private TrackListAdapter adapter; private TrackListAdapter adapter;
private TrackListBinding viewBinding; private TrackListBinding viewBinding;
@@ -138,13 +139,6 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
.observe(TrackListActivity.this, this::onGpsStatusChanged); .observe(TrackListActivity.this, this::onGpsStatusChanged);
updateGpsMenuItem(true, recordingStatus.isRecording()); updateGpsMenuItem(true, recordingStatus.isRecording());
if (service.getGpsStatusObservable().getValue().isGpsStarted()) {
return;
}
//TODO Not cool to do this in a callback that might be called more than once!
service.tryStartSensors();
}; };
@Override @Override
@@ -154,7 +148,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
requestRequiredPermissions(); requestRequiredPermissions();
trackRecordingServiceConnection = new TrackRecordingServiceConnection(bindChangedCallback); recordingStatusConnection = new TrackRecordingServiceConnection(bindChangedCallback);
viewBinding.aggregatedStatsButton.setOnClickListener((view) -> startActivity(IntentUtils.newIntent(this, AggregatedStatisticsActivity.class))); viewBinding.aggregatedStatsButton.setOnClickListener((view) -> startActivity(IntentUtils.newIntent(this, AggregatedStatisticsActivity.class)));
viewBinding.sensorStartButton.setOnClickListener((view) -> { viewBinding.sensorStartButton.setOnClickListener((view) -> {
@@ -163,9 +157,14 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)); startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
} else { } else {
if (gpsStatusValue.isGpsStarted()) { if (gpsStatusValue.isGpsStarted()) {
trackRecordingServiceConnection.unbindAndStop(this); recordingStatusConnection.unbindAndStop(this);
recordingStatusConnection.startConnection(this); //TODO We need to stay listening!
} else { } else {
trackRecordingServiceConnection.startAndBindWithCallback(this); new TrackRecordingServiceConnection((service, connection) -> {
service.tryStartSensors();
connection.unbind(this);
}).startAndBindWithCallback(this);
} }
} }
}); });
@@ -182,6 +181,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
} }
// Not Recording -> Recording // Not Recording -> Recording
Log.i(TAG, "Starting recording");
updateGpsMenuItem(false, true); updateGpsMenuItem(false, true);
new TrackRecordingServiceConnection((service, connection) -> { new TrackRecordingServiceConnection((service, connection) -> {
Track.Id trackId = service.startNewTrack(); Track.Id trackId = service.startNewTrack();
@@ -201,7 +201,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
// Recording -> Stop // Recording -> Stop
ActivityUtils.vibrate(this, 1000); ActivityUtils.vibrate(this, 1000);
updateGpsMenuItem(false, false); updateGpsMenuItem(false, false);
trackRecordingServiceConnection.stopRecording(TrackListActivity.this); recordingStatusConnection.stopRecording(TrackListActivity.this);
viewBinding.trackListFabAction.setImageResource(R.drawable.ic_baseline_record_24); viewBinding.trackListFabAction.setImageResource(R.drawable.ic_baseline_record_24);
viewBinding.trackListFabAction.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.red_dark)); viewBinding.trackListFabAction.setBackgroundTintList(ContextCompat.getColorStateList(this, R.color.red_dark));
return true; return true;
@@ -220,7 +220,7 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
super.onStart(); super.onStart();
PreferencesUtils.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); PreferencesUtils.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
trackRecordingServiceConnection.startConnection(this); recordingStatusConnection.startConnection(this);
} }
@Override @Override
@@ -240,14 +240,14 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co
super.onStop(); super.onStop();
PreferencesUtils.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); PreferencesUtils.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
trackRecordingServiceConnection.unbind(this); recordingStatusConnection.unbind(this);
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
viewBinding = null; viewBinding = null;
trackRecordingServiceConnection = null; recordingStatusConnection = null;
adapter = null; adapter = null;
} }
@@ -47,24 +47,23 @@ public class BluetoothConnectionManager {
private final SensorHandlerInterface sensorHandler; private final SensorHandlerInterface sensorHandler;
private BluetoothGatt bluetoothGatt; private BluetoothGatt bluetoothGatt;
private final BluetoothGattCallback connectCallback = new BluetoothGattCallback() { private final BluetoothGattCallback connectCallback = new BluetoothGattCallback() {
@Override @Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
switch (newState) { switch (newState) {
case BluetoothProfile.STATE_CONNECTING -> case BluetoothProfile.STATE_CONNECTING ->
Log.i(TAG, "Connecting to sensor: " + gatt.getDevice()); Log.i(TAG, gatt.getDevice() + ": connecting to sensor");
case BluetoothProfile.STATE_CONNECTED -> { case BluetoothProfile.STATE_CONNECTED -> {
Log.i(TAG, "Connected to sensor: " + gatt.getDevice() + "; discovering services."); Log.i(TAG, gatt.getDevice() + ": connected to sensor; discovering services");
gatt.discoverServices(); gatt.discoverServices();
} }
case BluetoothProfile.STATE_DISCONNECTING -> case BluetoothProfile.STATE_DISCONNECTING ->
Log.i(TAG, "Disconnecting from sensor: " + gatt.getDevice()); Log.i(TAG, gatt.getDevice() + ": disconnecting from sensor: ");
case BluetoothProfile.STATE_DISCONNECTED -> { case BluetoothProfile.STATE_DISCONNECTED -> {
//This is also triggered, if no connection was established (ca. 30s) //This is also triggered, if no connection was established (ca. 30s)
Log.i(TAG, "Disconnected from sensor: " + gatt.getDevice() + "; trying to reconnect"); Log.i(TAG, gatt.getDevice() + ": disconnected from sensor: trying to reconnect");
if (gatt.connect()) { if (gatt.connect()) {
Log.e(TAG, "Could not trigger reconnect for sensor: " + gatt.getDevice()); Log.e(TAG, gatt.getDevice() + ": could not trigger reconnect for sensor");
} }
clearData(); clearData();
} }
@@ -84,13 +83,13 @@ public class BluetoothConnectionManager {
} }
if (gattService == null) { if (gattService == null) {
Log.e(TAG, "Could not get gattService for address=" + gatt.getDevice().getAddress() + " serviceUUID=" + serviceMeasurement); Log.e(TAG, gatt.getDevice() + ": could not get gattService for serviceUUID=" + serviceMeasurement);
return; return;
} }
BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(serviceMeasurement.measurementUUID()); BluetoothGattCharacteristic characteristic = gattService.getCharacteristic(serviceMeasurement.measurementUUID());
if (characteristic == null) { if (characteristic == null) {
Log.e(TAG, "Could not get BluetoothCharacteristic for address=" + gatt.getDevice().getAddress() + " serviceUUID=" + serviceMeasurement.serviceUUID() + " characteristicUUID=" + serviceMeasurement.measurementUUID()); Log.e(TAG, gatt.getDevice() + ": could not get BluetoothCharacteristic for serviceUUID=" + serviceMeasurement.serviceUUID() + " characteristicUUID=" + serviceMeasurement.measurementUUID());
return; return;
} }
gatt.setCharacteristicNotification(characteristic, true); gatt.setCharacteristicNotification(characteristic, true);
@@ -110,13 +109,14 @@ public class BluetoothConnectionManager {
@Override @Override
public void onCharacteristicChanged(BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic) { public void onCharacteristicChanged(BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic) {
UUID serviceUUID = characteristic.getService().getUuid(); UUID serviceUUID = characteristic.getService().getUuid();
Log.d(TAG, "Received data from " + gatt.getDevice().getAddress() + " with service " + serviceUUID + " and characteristics " + characteristic.getUuid()); BluetoothDevice device = gatt.getDevice();
Log.d(TAG, device + ": Received data with service " + serviceUUID + " and characteristics " + characteristic.getUuid());
Optional<ServiceMeasurementUUID> serviceMeasurementUUID = sensorHandler.getServices() Optional<ServiceMeasurementUUID> serviceMeasurementUUID = sensorHandler.getServices()
.stream() .stream()
.filter(s -> s.serviceUUID().equals(characteristic.getService().getUuid())) .filter(s -> s.serviceUUID().equals(characteristic.getService().getUuid()))
.findFirst(); .findFirst();
if (serviceMeasurementUUID.isEmpty()) { if (serviceMeasurementUUID.isEmpty()) {
Log.e(TAG, "Unknown service UUID; not supported?"); Log.e(TAG, device + ": Unknown service UUID; not supported?");
return; return;
} }
@@ -135,24 +135,26 @@ public class BluetoothConnectionManager {
return; return;
} }
Log.d(TAG, "Connecting to: " + device); Log.d(TAG, device + ": trying to connect");
bluetoothGatt = device.connectGatt(context, false, connectCallback, BluetoothDevice.TRANSPORT_AUTO, 0, handler); bluetoothGatt = device.connectGatt(context, false, connectCallback, BluetoothDevice.TRANSPORT_AUTO, 0, handler);
observer.onConnect(sensorHandler.createEmptySensorData(bluetoothGatt.getDevice().getAddress())); observer.onConnect(sensorHandler.createEmptySensorData(device.getAddress(), device.getName()));
} }
private synchronized void clearData() { private synchronized void clearData() {
observer.onDisconnect(sensorHandler.createEmptySensorData(bluetoothGatt.getDevice().getAddress())); observer.onDisconnect(sensorHandler.createEmptySensorData(bluetoothGatt.getDevice().getAddress(), bluetoothGatt.getDevice().getName()));
} }
synchronized void disconnect() { synchronized void disconnect() {
if (bluetoothGatt == null) { if (bluetoothGatt == null) {
Log.w(TAG, "Cannot disconnect if not connected.");
return; return;
} }
Log.i(TAG, bluetoothGatt.getDevice() + ": start disconnect");
bluetoothGatt.disconnect();
bluetoothGatt.close(); bluetoothGatt.close();
clearData(); clearData();
Log.i(TAG, bluetoothGatt.getDevice() + ": disconnect finished");
bluetoothGatt = null; bluetoothGatt = null;
} }
@@ -22,7 +22,7 @@ public class BluetoothHandlerBarometricPressure implements SensorHandlerInterfac
} }
@Override @Override
public Aggregator<?, ?> createEmptySensorData(String address) { public Aggregator<?, ?> createEmptySensorData(String address, String name) {
return null; //TODO return null; //TODO
} }
@@ -24,8 +24,8 @@ public class BluetoothHandlerCyclingCadence implements SensorHandlerInterface {
} }
@Override @Override
public AggregatorCyclingCadence createEmptySensorData(String address) { public AggregatorCyclingCadence createEmptySensorData(String address, String name) {
return new AggregatorCyclingCadence(address); return new AggregatorCyclingCadence(address, name);
} }
@Override @Override
@@ -26,8 +26,8 @@ public class BluetoothHandlerCyclingDistanceSpeed implements SensorHandlerInterf
} }
@Override @Override
public AggregatorCyclingDistanceSpeed createEmptySensorData(String address) { public AggregatorCyclingDistanceSpeed createEmptySensorData(String address, String name) {
return new AggregatorCyclingDistanceSpeed(address); return new AggregatorCyclingDistanceSpeed(address, name);
} }
@Override @Override
@@ -26,8 +26,8 @@ public class BluetoothHandlerManagerCyclingPower implements SensorHandlerInterfa
} }
@Override @Override
public AggregatorCyclingPower createEmptySensorData(String address) { public AggregatorCyclingPower createEmptySensorData(String address, String name) {
return new AggregatorCyclingPower(address); return new AggregatorCyclingPower(address, name);
} }
@Override @Override
@@ -36,8 +36,8 @@ public class BluetoothHandlerManagerHeartRate implements SensorHandlerInterface
} }
@Override @Override
public AggregatorHeartRate createEmptySensorData(String address) { public AggregatorHeartRate createEmptySensorData(String address, String name) {
return new AggregatorHeartRate(address); return new AggregatorHeartRate(address, name);
} }
@Override @Override
@@ -29,8 +29,8 @@ public class BluetoothHandlerRunningSpeedAndCadence implements SensorHandlerInte
} }
@Override @Override
public AggregatorRunning createEmptySensorData(String address) { public AggregatorRunning createEmptySensorData(String address, String name) {
return new AggregatorRunning(address); return new AggregatorRunning(address, name);
} }
@Override @Override
@@ -57,6 +57,10 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
} }
public void start(Context context, Handler handler) { public void start(Context context, Handler handler) {
if (gpsManager != null) {
throw new RuntimeException("SensorManager cannot be started twice; stop first.");
}
gpsManager = new GPSManager(observer); //TODO Pass listener gpsManager = new GPSManager(observer); //TODO Pass listener
altitudeSumManager = new GainManager(listener); altitudeSumManager = new GainManager(listener);
bluetoothSensorManager = new BluetoothRemoteSensorManager(context, handler, listener); bluetoothSensorManager = new BluetoothRemoteSensorManager(context, handler, listener);
@@ -13,7 +13,7 @@ import java.util.concurrent.TimeUnit;
import de.dennisguse.opentracks.data.models.AtmosphericPressure; import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.sensors.GainManager; import de.dennisguse.opentracks.sensors.GainManager;
public class BarometerInternal implements SensorEventListener { public class BarometerInternal {
private static final String TAG = BarometerInternal.class.getSimpleName(); private static final String TAG = BarometerInternal.class.getSimpleName();
@@ -21,20 +21,22 @@ public class BarometerInternal implements SensorEventListener {
private GainManager observer; private GainManager observer;
@Override private final SensorEventListener listener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) { @Override
if (!isConnected()) { public void onSensorChanged(SensorEvent event) {
Log.w(TAG, "Not connected to sensor, cannot process data."); if (!isConnected()) {
return; Log.w(TAG, "Not connected to sensor, cannot process data.");
return;
}
observer.onSensorValueChanged(AtmosphericPressure.ofHPA(event.values[0]));
} }
observer.onSensorValueChanged(AtmosphericPressure.ofHPA(event.values[0])); @Override
} public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.w(TAG, "Sensor accuracy changes are (currently) ignored.");
@Override }
public void onAccuracyChanged(Sensor sensor, int accuracy) { };
Log.w(TAG, "Sensor accuracy changes are (currently) ignored.");
}
public void connect(Context context, Handler handler, GainManager observer) { public void connect(Context context, Handler handler, GainManager observer) {
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
@@ -42,9 +44,10 @@ public class BarometerInternal implements SensorEventListener {
if (pressureSensor == null) { if (pressureSensor == null) {
Log.w(TAG, "No pressure sensor available."); Log.w(TAG, "No pressure sensor available.");
this.observer = null; this.observer = null;
return;
} }
if (sensorManager.registerListener(this, pressureSensor, SAMPLING_PERIOD, handler)) { if (sensorManager.registerListener(listener, pressureSensor, SAMPLING_PERIOD, handler)) {
this.observer = observer; this.observer = observer;
return; return;
} }
@@ -54,7 +57,7 @@ public class BarometerInternal implements SensorEventListener {
public void disconnect(Context context) { public void disconnect(Context context) {
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensorManager.unregisterListener(this); sensorManager.unregisterListener(listener);
observer = null; observer = null;
} }
@@ -14,10 +14,6 @@ public class AggregatorCyclingCadence extends Aggregator<BluetoothHandlerCycling
private final String TAG = AggregatorCyclingCadence.class.getSimpleName(); private final String TAG = AggregatorCyclingCadence.class.getSimpleName();
public AggregatorCyclingCadence(String sensorAddress) {
super(sensorAddress);
}
public AggregatorCyclingCadence(String sensorAddress, String sensorName) { public AggregatorCyclingCadence(String sensorAddress, String sensorName) {
super(sensorAddress, sensorName); super(sensorAddress, sensorName);
} }
@@ -17,10 +17,6 @@ public class AggregatorCyclingDistanceSpeed extends Aggregator<BluetoothHandlerC
private Distance wheelCircumference; private Distance wheelCircumference;
public AggregatorCyclingDistanceSpeed(String sensorAddress) {
super(sensorAddress);
}
public AggregatorCyclingDistanceSpeed(String sensorAddress, String sensorName) { public AggregatorCyclingDistanceSpeed(String sensorAddress, String sensorName) {
super(sensorAddress, sensorName); super(sensorAddress, sensorName);
} }
@@ -6,10 +6,6 @@ import de.dennisguse.opentracks.data.models.Power;
public class AggregatorCyclingPower extends Aggregator<Power, Power> { public class AggregatorCyclingPower extends Aggregator<Power, Power> {
public AggregatorCyclingPower(String address) {
super(address);
}
public AggregatorCyclingPower(String name, String address) { public AggregatorCyclingPower(String name, String address) {
super(name, address); super(name, address);
} }
@@ -6,10 +6,6 @@ import de.dennisguse.opentracks.data.models.HeartRate;
public class AggregatorHeartRate extends Aggregator<HeartRate, HeartRate> { public class AggregatorHeartRate extends Aggregator<HeartRate, HeartRate> {
public AggregatorHeartRate(String address) {
super(address);
}
public AggregatorHeartRate(String name, String address) { public AggregatorHeartRate(String name, String address) {
super(name, address); super(name, address);
} }
@@ -14,10 +14,6 @@ public final class AggregatorRunning extends Aggregator<BluetoothHandlerRunningS
private static final String TAG = AggregatorRunning.class.getSimpleName(); private static final String TAG = AggregatorRunning.class.getSimpleName();
public AggregatorRunning(String sensorAddress) {
super(sensorAddress);
}
public AggregatorRunning(String sensorAddress, String sensorName) { public AggregatorRunning(String sensorAddress, String sensorName) {
super(sensorAddress, sensorName); super(sensorAddress, sensorName);
} }
@@ -188,7 +188,7 @@ public final class SensorDataSet {
} }
private void set(@NonNull Aggregator<?, ?> type, @Nullable Aggregator<?, ?> sensorData) { private void set(@NonNull Aggregator<?, ?> type, @Nullable Aggregator<?, ?> sensorData) {
Log.i(TAG, "Setting aggregator " + type.getClass().getCanonicalName()); Log.i(TAG, "Setting aggregator " + type.getClass().getCanonicalName() + " to " + sensorData);
if (type instanceof AggregatorHeartRate) { if (type instanceof AggregatorHeartRate) {
heartRate = (AggregatorHeartRate) sensorData; heartRate = (AggregatorHeartRate) sensorData;
@@ -11,7 +11,7 @@ public interface SensorHandlerInterface {
List<ServiceMeasurementUUID> getServices(); List<ServiceMeasurementUUID> getServices();
Aggregator<?, ?> createEmptySensorData(String address); Aggregator<?, ?> createEmptySensorData(String address, String name);
void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic); void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic);
} }
@@ -125,6 +125,9 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
if (isRecording()) { if (isRecording()) {
endCurrentTrack(); endCurrentTrack();
} }
if (isSensorStarted()) {
stopSensors();
}
PreferencesUtils.unregisterOnSharedPreferenceChangeListener(this); PreferencesUtils.unregisterOnSharedPreferenceChangeListener(this);
@@ -163,6 +166,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
Log.w(TAG, "Ignore startNewTrack. Already recording."); Log.w(TAG, "Ignore startNewTrack. Already recording.");
return null; return null;
} }
Log.i(TAG, "startNewTrack");
// Set recording status // Set recording status
Track.Id trackId = trackRecordingManager.startNewTrack(); Track.Id trackId = trackRecordingManager.startNewTrack();
@@ -177,6 +181,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
Log.w(TAG, "Cannot resume a non-existing track."); Log.w(TAG, "Cannot resume a non-existing track.");
return; return;
} }
Log.i(TAG, "resumeTrack");
updateRecordingStatus(RecordingStatus.record(trackId)); updateRecordingStatus(RecordingStatus.record(trackId));
@@ -193,12 +198,19 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
} }
public void tryStartSensors() { public void tryStartSensors() {
if (isRecording()) return; if (isSensorStarted()) return;
Log.i(TAG, "tryStartSensors");
startSensors(); startSensors();
} }
private void startSensors() { private synchronized void startSensors() {
if (isSensorStarted()) {
Log.i(TAG, "sensors already started; skipping");
return;
}
Log.i(TAG, "startSensors");
wakeLock = SystemUtils.acquireWakeLock(this, wakeLock); wakeLock = SystemUtils.acquireWakeLock(this, wakeLock);
trackPointCreator.start(this, handler); trackPointCreator.start(this, handler);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@@ -239,6 +251,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
stopForeground(true); stopForeground(true);
notificationManager.cancelNotification(); notificationManager.cancelNotification();
wakeLock = SystemUtils.releaseWakeLock(wakeLock); wakeLock = SystemUtils.releaseWakeLock(wakeLock);
gpsStatusObservable.postValue(STATUS_GPS_DEFAULT);
} }
@Override @Override
@@ -255,7 +268,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
@Override @Override
public void newGpsStatus(GpsStatusValue gpsStatusValue) { public void newGpsStatus(GpsStatusValue gpsStatusValue) {
Log.e(TAG, "newGpsStatus: " + gpsStatusValue.message); Log.i(TAG, "newGpsStatus: " + gpsStatusValue.message);
if (notificationManager == null) { if (notificationManager == null) {
@@ -336,6 +349,10 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
return recordingStatus.isRecording(); return recordingStatus.isRecording();
} }
private boolean isSensorStarted() {
return wakeLock != null;
}
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key) { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key) {
voiceAnnouncementManager.onSharedPreferenceChanged(sharedPreferences, key); voiceAnnouncementManager.onSharedPreferenceChanged(sharedPreferences, key);
@@ -127,9 +127,6 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
setTrackRecordingService(null); setTrackRecordingService(null);
} }
/**
* Unbinds and stops the service.
*/
public void unbindAndStop(Context context) { public void unbindAndStop(Context context) {
unbind(context); unbind(context);
context.stopService(new Intent(context, TrackRecordingService.class)); context.stopService(new Intent(context, TrackRecordingService.class));
@@ -153,7 +150,7 @@ public class TrackRecordingServiceConnection implements ServiceConnection, Death
@Override @Override
public void onServiceConnected(ComponentName className, IBinder service) { public void onServiceConnected(ComponentName className, IBinder service) {
Log.i(TAG, "Connected to the service."); Log.i(TAG, "Connected to the service: " + service);
try { try {
service.linkToDeath(this, 0); service.linkToDeath(this, 0);
} catch (RemoteException e) { } catch (RemoteException e) {