mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 12:53:55 +01:00
Fix security exception crash while accessing network location provider (#1498)
* Fix security exception crash while accessing network location provider * Added java docs
This commit is contained in:
parent
93b0db9ecd
commit
d891b8f310
2 changed files with 61 additions and 11 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
package fr.free.nrw.commons.location;
|
package fr.free.nrw.commons.location;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
|
@ -10,9 +11,10 @@ import android.location.LocationManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
@ -29,6 +31,7 @@ public class LocationServiceManager implements LocationListener {
|
||||||
private Location lastLocation;
|
private Location lastLocation;
|
||||||
private final List<LocationUpdateListener> locationListeners = new CopyOnWriteArrayList<>();
|
private final List<LocationUpdateListener> locationListeners = new CopyOnWriteArrayList<>();
|
||||||
private boolean isLocationManagerRegistered = false;
|
private boolean isLocationManagerRegistered = false;
|
||||||
|
private Set<Activity> locationExplanationDisplayed = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new instance of LocationServiceManager.
|
* Constructs a new instance of LocationServiceManager.
|
||||||
|
|
@ -51,7 +54,6 @@ public class LocationServiceManager implements LocationListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the location permission is granted.
|
* Returns whether the location permission is granted.
|
||||||
*
|
|
||||||
* @return true if the location permission is granted
|
* @return true if the location permission is granted
|
||||||
*/
|
*/
|
||||||
public boolean isLocationPermissionGranted() {
|
public boolean isLocationPermissionGranted() {
|
||||||
|
|
@ -73,10 +75,23 @@ public class LocationServiceManager implements LocationListener {
|
||||||
LOCATION_REQUEST);
|
LOCATION_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The permission explanation dialog box is now displayed just once for a particular activity. We are subscribing
|
||||||
|
* to updates from multiple providers so its important to show the dialog just once. Otherwise it will be displayed
|
||||||
|
* once for every provider, which in our case currently is 2.
|
||||||
|
* @param activity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public boolean isPermissionExplanationRequired(Activity activity) {
|
public boolean isPermissionExplanationRequired(Activity activity) {
|
||||||
return !activity.isFinishing() &&
|
if (activity.isFinishing()) {
|
||||||
ActivityCompat.shouldShowRequestPermissionRationale(activity,
|
return false;
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION);
|
}
|
||||||
|
boolean showRequestPermissionRationale = ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION);
|
||||||
|
if (showRequestPermissionRationale && !locationExplanationDisplayed.contains(activity)) {
|
||||||
|
locationExplanationDisplayed.add(activity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -84,8 +99,9 @@ public class LocationServiceManager implements LocationListener {
|
||||||
* (e.g. when Location permission just granted)
|
* (e.g. when Location permission just granted)
|
||||||
* @return last known LatLng
|
* @return last known LatLng
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
public LatLng getLKL() {
|
public LatLng getLKL() {
|
||||||
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
if (isLocationPermissionGranted()) {
|
||||||
Location lastKL = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
|
Location lastKL = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
|
||||||
if (lastKL == null) {
|
if (lastKL == null) {
|
||||||
lastKL = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
|
lastKL = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
|
||||||
|
|
@ -107,10 +123,11 @@ public class LocationServiceManager implements LocationListener {
|
||||||
* Registers a LocationManager to listen for current location.
|
* Registers a LocationManager to listen for current location.
|
||||||
*/
|
*/
|
||||||
public void registerLocationManager() {
|
public void registerLocationManager() {
|
||||||
if (!isLocationManagerRegistered)
|
if (!isLocationManagerRegistered) {
|
||||||
isLocationManagerRegistered = requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER)
|
isLocationManagerRegistered = requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER)
|
||||||
&& requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER);
|
&& requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests location updates from the specified provider.
|
* Requests location updates from the specified provider.
|
||||||
|
|
@ -142,7 +159,7 @@ public class LocationServiceManager implements LocationListener {
|
||||||
* @return LOCATION_SIGNIFICANTLY_CHANGED if location changed significantly
|
* @return LOCATION_SIGNIFICANTLY_CHANGED if location changed significantly
|
||||||
* LOCATION_SLIGHTLY_CHANGED if location changed slightly
|
* LOCATION_SLIGHTLY_CHANGED if location changed slightly
|
||||||
*/
|
*/
|
||||||
protected LocationChangeType isBetterLocation(Location location, Location currentBestLocation) {
|
private LocationChangeType isBetterLocation(Location location, Location currentBestLocation) {
|
||||||
|
|
||||||
if (currentBestLocation == null) {
|
if (currentBestLocation == null) {
|
||||||
// A new location is always better than no location
|
// A new location is always better than no location
|
||||||
|
|
|
||||||
|
|
@ -322,7 +322,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
locationManager.addLocationListener(this);
|
locationManager.addLocationListener(this);
|
||||||
locationManager.registerLocationManager();
|
registerLocationUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -400,7 +400,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
locationManager.registerLocationManager();
|
registerLocationUpdates();
|
||||||
LatLng lastLocation = locationManager.getLastLocation();
|
LatLng lastLocation = locationManager.getLastLocation();
|
||||||
|
|
||||||
if (curLatLng != null && curLatLng.equals(lastLocation)) { //refresh view only if location has changed
|
if (curLatLng != null && curLatLng.equals(lastLocation)) { //refresh view only if location has changed
|
||||||
|
|
@ -450,6 +450,39 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method first checks if the location permissions has been granted and then register the location manager for updates.
|
||||||
|
*/
|
||||||
|
private void registerLocationUpdates() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
if (locationManager.isLocationPermissionGranted()) {
|
||||||
|
locationManager.registerLocationManager();
|
||||||
|
} else {
|
||||||
|
// Should we show an explanation?
|
||||||
|
if (locationManager.isPermissionExplanationRequired(this)) {
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setMessage(getString(R.string.location_permission_rationale_nearby))
|
||||||
|
.setPositiveButton("OK", (dialog, which) -> {
|
||||||
|
requestLocationPermissions();
|
||||||
|
dialog.dismiss();
|
||||||
|
})
|
||||||
|
.setNegativeButton("Cancel", (dialog, id) -> {
|
||||||
|
showLocationPermissionDeniedErrorDialog();
|
||||||
|
dialog.cancel();
|
||||||
|
})
|
||||||
|
.create()
|
||||||
|
.show();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// No explanation needed, we can request the permission.
|
||||||
|
requestLocationPermissions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
locationManager.registerLocationManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void populatePlaces(NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
|
private void populatePlaces(NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
|
||||||
List<Place> placeList = nearbyPlacesInfo.placeList;
|
List<Place> placeList = nearbyPlacesInfo.placeList;
|
||||||
LatLng[] boundaryCoordinates = nearbyPlacesInfo.boundaryCoordinates;
|
LatLng[] boundaryCoordinates = nearbyPlacesInfo.boundaryCoordinates;
|
||||||
|
|
@ -530,7 +563,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
||||||
locationManager.removeLocationListener(this);
|
locationManager.removeLocationListener(this);
|
||||||
} else {
|
} else {
|
||||||
lockNearbyView = false;
|
lockNearbyView = false;
|
||||||
locationManager.registerLocationManager();
|
registerLocationUpdates();
|
||||||
locationManager.addLocationListener(this);
|
locationManager.addLocationListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue