forked from upstream-mirrors/OpenTracks
Extract Driver for internal GPS to GpsInternal.
This commit is contained in:
+1
-1
@@ -756,6 +756,6 @@ public class ExportImportTest {
|
|||||||
mockAltitudeChange(trackPointCreator, altitudeGain);
|
mockAltitudeChange(trackPointCreator, altitudeGain);
|
||||||
|
|
||||||
trackPointCreator.setClock(time);
|
trackPointCreator.setClock(time);
|
||||||
trackPointCreator.getSensorManager().getGpsManager().onLocationChanged(location);
|
trackPointCreator.getSensorManager().getGpsManager().onData(location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-4
@@ -6,11 +6,9 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationManager;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.location.LocationManagerCompat;
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import androidx.test.filters.MediumTest;
|
import androidx.test.filters.MediumTest;
|
||||||
@@ -153,7 +151,7 @@ public class TrackRecordingServiceRecordingTest {
|
|||||||
Track.Id trackId = service.startNewTrack();
|
Track.Id trackId = service.startNewTrack();
|
||||||
|
|
||||||
//We do not want the real GPS to interfere.
|
//We do not want the real GPS to interfere.
|
||||||
LocationManagerCompat.removeUpdates((LocationManager) context.getSystemService(Context.LOCATION_SERVICE), trackPointCreator.getSensorManager().getGpsManager());
|
trackPointCreator.getSensorManager().getGpsManager().driver.disconnect();
|
||||||
|
|
||||||
String gps1 = "2020-02-02T02:02:03Z";
|
String gps1 = "2020-02-02T02:02:03Z";
|
||||||
sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15);
|
sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15);
|
||||||
@@ -987,6 +985,6 @@ public class TrackRecordingServiceRecordingTest {
|
|||||||
location.setSpeed(speed);
|
location.setSpeed(speed);
|
||||||
|
|
||||||
trackPointCreator.setClock(time);
|
trackPointCreator.setClock(time);
|
||||||
trackPointCreator.getSensorManager().getGpsManager().onLocationChanged(location);
|
trackPointCreator.getSensorManager().getGpsManager().onData(location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,34 +3,26 @@ package de.dennisguse.opentracks.sensors;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.core.location.LocationListenerCompat;
|
|
||||||
import androidx.core.location.LocationManagerCompat;
|
|
||||||
import androidx.core.location.LocationRequestCompat;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.data.models.Distance;
|
import de.dennisguse.opentracks.data.models.Distance;
|
||||||
import de.dennisguse.opentracks.data.models.Position;
|
import de.dennisguse.opentracks.data.models.Position;
|
||||||
|
import de.dennisguse.opentracks.sensors.driver.DriverObserver;
|
||||||
|
import de.dennisguse.opentracks.sensors.driver.GpsInternal;
|
||||||
import de.dennisguse.opentracks.sensors.sensorData.AggregatorGPS;
|
import de.dennisguse.opentracks.sensors.sensorData.AggregatorGPS;
|
||||||
import de.dennisguse.opentracks.services.handlers.TrackPointCreator;
|
import de.dennisguse.opentracks.services.handlers.TrackPointCreator;
|
||||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.PermissionRequester;
|
|
||||||
|
|
||||||
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
|
||||||
public class GpsManager implements LocationListenerCompat, GpsStatusManager.GpsStatusListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
public class GpsManager implements DriverObserver<Location>, GpsStatusManager.GpsStatusListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
private final String TAG = GpsManager.class.getSimpleName();
|
private final String TAG = GpsManager.class.getSimpleName();
|
||||||
|
|
||||||
private static final String LOCATION_PROVIDER = LocationManager.GPS_PROVIDER;
|
|
||||||
|
|
||||||
//TODO Refactor to just pass information via SensorManager.
|
//TODO Refactor to just pass information via SensorManager.
|
||||||
private TrackPointCreator trackPointCreator;
|
private TrackPointCreator trackPointCreator;
|
||||||
|
|
||||||
@@ -38,9 +30,9 @@ public class GpsManager implements LocationListenerCompat, GpsStatusManager.GpsS
|
|||||||
private Context context;
|
private Context context;
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
|
|
||||||
private LocationManager locationManager;
|
@VisibleForTesting
|
||||||
|
public GpsInternal driver;
|
||||||
private GpsStatusManager gpsStatusManager;
|
private GpsStatusManager gpsStatusManager;
|
||||||
private Duration gpsInterval;
|
|
||||||
private Distance thresholdHorizontalAccuracy;
|
private Distance thresholdHorizontalAccuracy;
|
||||||
|
|
||||||
private AggregatorGPS aggregatorGPS;
|
private AggregatorGPS aggregatorGPS;
|
||||||
@@ -57,24 +49,20 @@ public class GpsManager implements LocationListenerCompat, GpsStatusManager.GpsS
|
|||||||
onSharedPreferenceChanged(null, null);
|
onSharedPreferenceChanged(null, null);
|
||||||
|
|
||||||
gpsStatusManager = new GpsStatusManager(context, this, handler);
|
gpsStatusManager = new GpsStatusManager(context, this, handler);
|
||||||
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
|
||||||
|
|
||||||
this.aggregatorGPS = new AggregatorGPS("internal");
|
this.aggregatorGPS = new AggregatorGPS("internal");
|
||||||
|
|
||||||
registerLocationListener();
|
this.driver = new GpsInternal(this);
|
||||||
|
this.driver.connect(context, handler, "internal");
|
||||||
gpsStatusManager.start();
|
gpsStatusManager.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isStarted() {
|
|
||||||
return locationManager != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"MissingPermission"})
|
@SuppressWarnings({"MissingPermission"})
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (isStarted()) {
|
if (driver.isConnected()) {
|
||||||
LocationManagerCompat.removeUpdates(locationManager, this);
|
driver.disconnect();
|
||||||
}
|
}
|
||||||
locationManager = null;
|
driver = null;
|
||||||
this.context = null;
|
this.context = null;
|
||||||
handler = null;
|
handler = null;
|
||||||
|
|
||||||
@@ -106,36 +94,48 @@ public class GpsManager implements LocationListenerCompat, GpsStatusManager.GpsS
|
|||||||
if (PreferencesUtils.isKey(R.string.min_sampling_interval_key, key)) {
|
if (PreferencesUtils.isKey(R.string.min_sampling_interval_key, key)) {
|
||||||
registerListener = true;
|
registerListener = true;
|
||||||
|
|
||||||
gpsInterval = PreferencesUtils.getMinSamplingInterval();
|
|
||||||
|
|
||||||
if (gpsStatusManager != null) {
|
if (gpsStatusManager != null) {
|
||||||
gpsStatusManager.onMinSamplingIntervalChanged(gpsInterval);
|
gpsStatusManager.onMinSamplingIntervalChanged(PreferencesUtils.getMinSamplingInterval());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (PreferencesUtils.isKey(R.string.recording_gps_accuracy_key, key)) {
|
if (PreferencesUtils.isKey(R.string.recording_gps_accuracy_key, key)) {
|
||||||
thresholdHorizontalAccuracy = PreferencesUtils.getThresholdHorizontalAccuracy();
|
thresholdHorizontalAccuracy = PreferencesUtils.getThresholdHorizontalAccuracy();
|
||||||
}
|
}
|
||||||
if (PreferencesUtils.isKey(R.string.recording_distance_interval_key, key)) {
|
if (PreferencesUtils.isKey(R.string.recording_distance_interval_key, key)) {
|
||||||
registerListener = true;
|
|
||||||
|
|
||||||
if (gpsStatusManager != null) {
|
if (gpsStatusManager != null) {
|
||||||
Distance gpsMinDistance = PreferencesUtils.getRecordingDistanceInterval();
|
Distance gpsMinDistance = PreferencesUtils.getRecordingDistanceInterval();
|
||||||
gpsStatusManager.onRecordingDistanceChanged(gpsMinDistance);
|
gpsStatusManager.onRecordingDistanceChanged(gpsMinDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registerListener && isStarted()) {
|
if (registerListener && driver != null && driver.isConnected()) {
|
||||||
registerLocationListener();
|
driver.disconnect();
|
||||||
|
driver.connect(context, handler, "internal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if location is valid and builds a track point that will be send through TrackPointCreator.
|
|
||||||
*
|
|
||||||
* @param location {@link Location} object.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void onLocationChanged(@NonNull Location location) {
|
public void onGpsStatusChanged(GpsStatusValue currentStatus) {
|
||||||
|
trackPointCreator.sendGpsStatus(currentStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnect() {
|
||||||
|
gpsStatusManager.onGpsEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect() {
|
||||||
|
gpsStatusManager.onGpsDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove() {
|
||||||
|
gpsStatusManager.onGpsDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onData(Location location) {
|
||||||
// Send each update to the status; please note that this TrackPoint is not stored.
|
// Send each update to the status; please note that this TrackPoint is not stored.
|
||||||
Position position = Position.of(location, observer.getNow());
|
Position position = Position.of(location, observer.getNow());
|
||||||
gpsStatusManager.onNewTrackPoint(position);
|
gpsStatusManager.onNewTrackPoint(position);
|
||||||
@@ -153,44 +153,4 @@ public class GpsManager implements LocationListenerCompat, GpsStatusManager.GpsS
|
|||||||
aggregatorGPS.add(observer.getNow(), position);
|
aggregatorGPS.add(observer.getNow(), position);
|
||||||
observer.onChange();
|
observer.onChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStatusChanged(@NonNull String provider, int status, Bundle extras) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProviderEnabled(@NonNull String provider) {
|
|
||||||
gpsStatusManager.onGpsEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProviderDisabled(@NonNull String provider) {
|
|
||||||
gpsStatusManager.onGpsDisabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerLocationListener() {
|
|
||||||
if (!LocationManagerCompat.hasProvider(locationManager, LOCATION_PROVIDER)) {
|
|
||||||
Log.e(TAG, "Device doesn't have GPS.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocationRequestCompat locationRequest = new LocationRequestCompat.Builder(gpsInterval.toMillis())
|
|
||||||
.setQuality(LocationRequestCompat.QUALITY_HIGH_ACCURACY)
|
|
||||||
.setMaxUpdateDelayMillis(0)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
if (PermissionRequester.GPS.hasPermission(context)) {
|
|
||||||
try {
|
|
||||||
Log.i(TAG, "Register for location updates " + context);
|
|
||||||
LocationManagerCompat.requestLocationUpdates(locationManager, LOCATION_PROVIDER, locationRequest, handler::post, this);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
Log.e(TAG, "Could not register location listener; permissions not granted.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGpsStatusChanged(GpsStatusValue currentStatus) {
|
|
||||||
trackPointCreator.sendGpsStatus(currentStatus);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package de.dennisguse.opentracks.sensors.driver;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.location.Location;
|
||||||
|
import android.location.LocationManager;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.location.LocationListenerCompat;
|
||||||
|
import androidx.core.location.LocationManagerCompat;
|
||||||
|
import androidx.core.location.LocationRequestCompat;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||||
|
import de.dennisguse.opentracks.util.PermissionRequester;
|
||||||
|
|
||||||
|
public class GpsInternal implements Driver {
|
||||||
|
|
||||||
|
private static final String TAG = GpsInternal.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final String LOCATION_PROVIDER = LocationManager.GPS_PROVIDER;
|
||||||
|
|
||||||
|
private final LocationListenerCompat locationListenerCompat = new LocationListenerCompat() {
|
||||||
|
@Override
|
||||||
|
public void onLocationChanged(@NonNull Location location) {
|
||||||
|
driverObserver.onData(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProviderEnabled(@NonNull String provider) {
|
||||||
|
driverObserver.onConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProviderDisabled(@NonNull String provider) {
|
||||||
|
driverObserver.onDisconnect();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final DriverObserver<Location> driverObserver;
|
||||||
|
|
||||||
|
private LocationManager locationManager;
|
||||||
|
|
||||||
|
public GpsInternal(DriverObserver<Location> driverObserver) {
|
||||||
|
this.driverObserver = driverObserver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect(Context context, Handler handler, String address) {
|
||||||
|
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||||
|
|
||||||
|
if (!LocationManagerCompat.hasProvider(locationManager, LOCATION_PROVIDER)) {
|
||||||
|
Log.e(TAG, "Device doesn't have GPS.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationRequestCompat locationRequest = new LocationRequestCompat.Builder(PreferencesUtils.getMinSamplingInterval().toMillis())
|
||||||
|
.setQuality(LocationRequestCompat.QUALITY_HIGH_ACCURACY)
|
||||||
|
.setMaxUpdateDelayMillis(0)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
if (PermissionRequester.GPS.hasPermission(context)) {
|
||||||
|
try {
|
||||||
|
Log.i(TAG, "Register for location updates " + context);
|
||||||
|
LocationManagerCompat.requestLocationUpdates(locationManager, LOCATION_PROVIDER, locationRequest, handler::post, locationListenerCompat);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
Log.e(TAG, "Could not register location listener; permissions not granted.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"MissingPermission"})
|
||||||
|
@Override
|
||||||
|
public void disconnect() {
|
||||||
|
if (!isConnected()) return;
|
||||||
|
|
||||||
|
LocationManagerCompat.removeUpdates(locationManager, locationListenerCompat);
|
||||||
|
|
||||||
|
locationManager = null;
|
||||||
|
driverObserver.onDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isConnected() {
|
||||||
|
return locationManager != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -579,6 +579,7 @@ public class PreferencesUtils {
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO Rename to getGpsMinSamplingInterval
|
||||||
public static Duration getMinSamplingInterval() {
|
public static Duration getMinSamplingInterval() {
|
||||||
final Duration MIN_SAMPLING_INTERVAL = getMinSamplingIntervalDefault();
|
final Duration MIN_SAMPLING_INTERVAL = getMinSamplingIntervalDefault();
|
||||||
return Duration.ofSeconds(getInt(R.string.min_sampling_interval_key, (int) MIN_SAMPLING_INTERVAL.getSeconds()));
|
return Duration.ofSeconds(getInt(R.string.min_sampling_interval_key, (int) MIN_SAMPLING_INTERVAL.getSeconds()));
|
||||||
|
|||||||
Reference in New Issue
Block a user