Handle LocationManager callbacks with TrackRecordingService's handler.
This commit is contained in:
Dennis Guse
2022-10-28 22:55:40 +02:00
committed by GitHub
4 changed files with 27 additions and 8 deletions
@@ -1,3 +1,6 @@
# We have flaky test results due to performance limitations in Github Actions.
# Happens too often nowadays; See https://github.com/OpenTracksApp/OpenTracks/issues/1409
#https://github.com/marketplace/actions/android-emulator-runner #https://github.com/marketplace/actions/android-emulator-runner
name: Test name: Test
on: on:
@@ -6,6 +6,7 @@ import static org.mockito.Mockito.verify;
import android.content.Context; import android.content.Context;
import android.location.Location; import android.location.Location;
import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
@@ -49,7 +50,7 @@ public class GPSHandlerTest {
Mockito.when(trackPointCreator.createNow()) Mockito.when(trackPointCreator.createNow())
.thenReturn(Instant.now()); .thenReturn(Instant.now());
locationHandler.onStart(context); locationHandler.onStart(context, new Handler());
} }
/** /**
@@ -3,14 +3,16 @@ package de.dennisguse.opentracks.services.handlers;
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.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
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.LocationManagerCompat;
import androidx.core.location.LocationRequestCompat;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
@@ -23,12 +25,16 @@ import de.dennisguse.opentracks.util.LocationUtils;
import de.dennisguse.opentracks.util.PermissionRequester; import de.dennisguse.opentracks.util.PermissionRequester;
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
public class GPSHandler implements LocationListener, GpsStatus.GpsStatusListener, SharedPreferences.OnSharedPreferenceChangeListener { public class GPSHandler implements LocationListenerCompat, GpsStatus.GpsStatusListener, SharedPreferences.OnSharedPreferenceChangeListener {
private final String TAG = GPSHandler.class.getSimpleName(); private final String TAG = GPSHandler.class.getSimpleName();
public static final String LOCATION_PROVIDER = LocationManager.GPS_PROVIDER;
private final TrackPointCreator trackPointCreator; private final TrackPointCreator trackPointCreator;
private Context context; private Context context;
private Handler handler;
private LocationManager locationManager; private LocationManager locationManager;
private GpsStatus gpsStatus; private GpsStatus gpsStatus;
private Duration gpsInterval; private Duration gpsInterval;
@@ -38,8 +44,10 @@ public class GPSHandler implements LocationListener, GpsStatus.GpsStatusListener
this.trackPointCreator = trackPointCreator; this.trackPointCreator = trackPointCreator;
} }
public void onStart(@NonNull Context context) { public void onStart(@NonNull Context context, @NonNull Handler handler) {
this.context = context; this.context = context;
this.handler = handler;
PreferencesUtils.registerOnSharedPreferenceChangeListener(this); PreferencesUtils.registerOnSharedPreferenceChangeListener(this);
gpsStatus = new GpsStatus(context, this); gpsStatus = new GpsStatus(context, this);
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
@@ -56,10 +64,11 @@ public class GPSHandler implements LocationListener, GpsStatus.GpsStatusListener
public void onStop() { public void onStop() {
if (locationManager != null && context != null) { if (locationManager != null && context != null) {
if (PermissionRequester.GPS.hasPermission(context)) { if (PermissionRequester.GPS.hasPermission(context)) {
locationManager.removeUpdates(this); LocationManagerCompat.removeUpdates(locationManager, this);
} }
locationManager = null; locationManager = null;
context = null; context = null;
handler = null;
} }
if (gpsStatus != null) { if (gpsStatus != null) {
@@ -154,14 +163,20 @@ public class GPSHandler implements LocationListener, GpsStatus.GpsStatusListener
return; return;
} }
if(!LocationManagerCompat.hasProvider(locationManager, LocationManager.GPS_PROVIDER)) { if (!LocationManagerCompat.hasProvider(locationManager, LOCATION_PROVIDER)) {
Log.e(TAG, "Device doesn't have GPS."); Log.e(TAG, "Device doesn't have GPS.");
return; return;
} }
LocationRequestCompat locationRequest = new LocationRequestCompat.Builder(gpsInterval.toMillis())
.setQuality(LocationRequestCompat.QUALITY_HIGH_ACCURACY)
.setMaxUpdateDelayMillis(0)
.build();
if (PermissionRequester.GPS.hasPermission(context)) { if (PermissionRequester.GPS.hasPermission(context)) {
try { try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, gpsInterval.toMillis(), 0, this); final Handler HANDLER = handler;
LocationManagerCompat.requestLocationUpdates(locationManager, LOCATION_PROVIDER, locationRequest, HANDLER::post, this);
} catch (SecurityException e) { } catch (SecurityException e) {
Log.e(TAG, "Could not register location listener; permissions not granted.", e); Log.e(TAG, "Could not register location listener; permissions not granted.", e);
} }
@@ -52,7 +52,7 @@ public class TrackPointCreator implements BluetoothRemoteSensorManager.SensorDat
public synchronized void start(@NonNull Context context, @NonNull Handler handler) { public synchronized void start(@NonNull Context context, @NonNull Handler handler) {
this.context = context; this.context = context;
gpsHandler.onStart(context); gpsHandler.onStart(context, handler);
remoteSensorManager = new BluetoothRemoteSensorManager(context, handler, this); remoteSensorManager = new BluetoothRemoteSensorManager(context, handler, this);
altitudeSumManager = new AltitudeSumManager(); altitudeSumManager = new AltitudeSumManager();