diff --git a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java index 706eb1133..103ef8fa4 100644 --- a/src/main/java/de/dennisguse/opentracks/TrackListActivity.java +++ b/src/main/java/de/dennisguse/opentracks/TrackListActivity.java @@ -16,13 +16,11 @@ package de.dennisguse.opentracks; -import android.Manifest; import android.app.ActivityOptions; import android.app.SearchManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.drawable.AnimatedVectorDrawable; import android.location.LocationManager; @@ -33,15 +31,11 @@ import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.Toast; -import androidx.activity.result.ActivityResultLauncher; -import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; -import androidx.core.app.ActivityCompat; import androidx.cursoradapter.widget.ResourceCursorAdapter; import androidx.loader.app.LoaderManager; import androidx.loader.content.CursorLoader; @@ -213,8 +207,6 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co ActivityUtils.configureListViewContextualMenu(viewBinding.trackList, contextualActionModeCallback); loadData(getIntent()); - - requestGPSPermissions(); } @Override @@ -392,26 +384,6 @@ public class TrackListActivity extends AbstractTrackDeleteActivity implements Co return recordingStatus.getTrackId(); } - private void requestGPSPermissions() { - if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED - && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { - return; - } - - ActivityResultLauncher locationPermissionRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> { - Boolean fineLocationGranted = result.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false); - Boolean coarseLocationGranted = result.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false); - if (fineLocationGranted == null || !fineLocationGranted - || coarseLocationGranted == null || !coarseLocationGranted) { - Toast.makeText(this, R.string.permission_gps_failed, Toast.LENGTH_SHORT).show(); - finish(); - } - } - ); - String[] permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}; - locationPermissionRequest.launch(permissions); - } - /** * Updates the menu items with the icon specified. * diff --git a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java index a205abf99..9231b972d 100644 --- a/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java +++ b/src/main/java/de/dennisguse/opentracks/TrackRecordingActivity.java @@ -1,5 +1,6 @@ package de.dennisguse.opentracks; +import android.Manifest; import android.app.AlertDialog; import android.content.Intent; import android.content.SharedPreferences; @@ -11,7 +12,10 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.WindowManager; +import android.widget.Toast; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; @@ -39,6 +43,7 @@ import de.dennisguse.opentracks.ui.markers.MarkerEditActivity; import de.dennisguse.opentracks.ui.markers.MarkerListActivity; import de.dennisguse.opentracks.util.IntentDashboardUtils; import de.dennisguse.opentracks.util.IntentUtils; +import de.dennisguse.opentracks.util.PermissionUtils; import de.dennisguse.opentracks.util.TrackIconUtils; import de.dennisguse.opentracks.util.TrackUtils; @@ -142,6 +147,8 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc if (savedInstanceState != null) { viewBinding.trackDetailActivityViewPager.setCurrentItem(savedInstanceState.getInt(CURRENT_TAB_TAG_KEY)); } + + requestGPSPermissions(); } @Override @@ -400,4 +407,22 @@ public class TrackRecordingActivity extends AbstractActivity implements ChooseAc setLockscreenPolicy(); setScreenOnPolicy(); } + + private void requestGPSPermissions() { + if (PermissionUtils.hasGPSPermission(this)) { + return; + } + + ActivityResultLauncher locationPermissionRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> { + Boolean fineLocationGranted = result.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false); + Boolean coarseLocationGranted = result.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false); + if (fineLocationGranted == null || !fineLocationGranted + || coarseLocationGranted == null || !coarseLocationGranted) { + Toast.makeText(this, R.string.permission_gps_failed, Toast.LENGTH_SHORT).show(); + } + } + ); + String[] permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}; + locationPermissionRequest.launch(permissions); + } } diff --git a/src/main/java/de/dennisguse/opentracks/services/handlers/GPSHandler.java b/src/main/java/de/dennisguse/opentracks/services/handlers/GPSHandler.java index e00939e67..5e499444c 100644 --- a/src/main/java/de/dennisguse/opentracks/services/handlers/GPSHandler.java +++ b/src/main/java/de/dennisguse/opentracks/services/handlers/GPSHandler.java @@ -18,14 +18,16 @@ import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.util.LocationUtils; +import de.dennisguse.opentracks.util.PermissionUtils; @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public class GPSHandler implements LocationListener, GpsStatus.GpsStatusListener, SharedPreferences.OnSharedPreferenceChangeListener { private final String TAG = GPSHandler.class.getSimpleName(); - private LocationManager locationManager; private final TrackPointCreator trackPointCreator; + private Context context; + private LocationManager locationManager; private GpsStatus gpsStatus; private Duration gpsInterval; private Distance thresholdHorizontalAccuracy; @@ -36,6 +38,7 @@ public class GPSHandler implements LocationListener, GpsStatus.GpsStatusListener } public void onStart(@NonNull Context context) { + this.context = context; PreferencesUtils.registerOnSharedPreferenceChangeListener(this); gpsStatus = new GpsStatus(context, this); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); @@ -51,9 +54,12 @@ public class GPSHandler implements LocationListener, GpsStatus.GpsStatusListener //TODO upgrade to AGP7.0.0/API31 started complaining about removeUpdates. public void onStop() { lastTrackPoint = null; - if (locationManager != null) { - locationManager.removeUpdates(this); + if (locationManager != null && context != null) { + if (PermissionUtils.hasGPSPermission(context)) { + locationManager.removeUpdates(this); + } locationManager = null; + context = null; } if (gpsStatus != null) { @@ -146,14 +152,16 @@ public class GPSHandler implements LocationListener, GpsStatus.GpsStatusListener } private void registerLocationListener() { - if (locationManager == null) { - Log.e(TAG, "locationManager is null."); + if (locationManager == null || context == null) { + Log.e(TAG, "Not started."); return; } - try { - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, gpsInterval.toMillis(), 0, this); - } catch (SecurityException e) { - Log.e(TAG, "Could not register location listener; permissions not granted.", e); + if (PermissionUtils.hasGPSPermission(context)) { + try { + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, gpsInterval.toMillis(), 0, this); + } catch (SecurityException e) { + Log.e(TAG, "Could not register location listener; permissions not granted.", e); + } } } diff --git a/src/main/java/de/dennisguse/opentracks/util/PermissionUtils.java b/src/main/java/de/dennisguse/opentracks/util/PermissionUtils.java new file mode 100644 index 000000000..b2ffb37aa --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/util/PermissionUtils.java @@ -0,0 +1,18 @@ +package de.dennisguse.opentracks.util; + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; + +import androidx.core.content.ContextCompat; + +public class PermissionUtils { + + private PermissionUtils() { + } + + public static boolean hasGPSPermission(Context context) { + return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED + && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; + } +}