Fix location permission requirement

Add feature to extract location rom EXIF data which works when location permission has not been granted yet. Also does not find location when uploading an image which already has a location in EXIF.
This commit is contained in:
Adam Jones 2016-06-09 14:53:14 +01:00
parent 6adf78bec9
commit d5278f0c85
3 changed files with 121 additions and 60 deletions

View file

@ -9,6 +9,7 @@ import android.location.LocationManager;
import android.media.ExifInterface;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.Snackbar;
import android.util.Log;
import java.io.IOException;
@ -71,7 +72,7 @@ public class GPSExtractor {
* Extracts geolocation of image from EXIF data.
* @return coordinates of image as string (needs to be passed as a String in API query)
*/
public String getCoords() {
public String getCoords(boolean useGPS) {
ExifInterface exif;
String latitude = "";
@ -87,25 +88,27 @@ public class GPSExtractor {
return null;
}
if (exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) == null) {
if (exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) == null && useGPS) {
registerLocationManager();
imageCoordsExists = false;
Log.d(TAG, "Picture has no GPS info");
Log.d(TAG, "EXIF data has no location info");
//Check what user's preference is for automatic location detection
boolean gpsPrefEnabled = gpsPreferenceEnabled();
if (gpsPrefEnabled) {
Log.d(TAG, "Current location values: Lat = " + currentLatitude + " Long = " + currentLongitude);
String currentCoords = String.valueOf(currentLatitude) + "|" + String.valueOf(currentLongitude);
return currentCoords;
return String.valueOf(currentLatitude) + "|" + String.valueOf(currentLongitude);
} else {
//Otherwise treat as if no coords found
// No coords found
return null;
}
} else if(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) == null) {
return null;
} else {
imageCoordsExists = true;
Log.d(TAG, "Picture has GPS info");
Log.d(TAG, "EXIF data has location info");
latitude = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
latitude_ref = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);

View file

@ -65,6 +65,12 @@ public class ShareActivity
private boolean cacheFound;
private GPSExtractor imageObj;
private String filePath;
private String decimalCoords;
private boolean useNewPermissions = false;
private boolean storagePermission = false;
private boolean locationPermission = false;
public ShareActivity() {
super(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE);
@ -216,12 +222,19 @@ public class ShareActivity
Log.d(TAG, "Uri: " + mediaUriString);
Log.d(TAG, "Ext storage dir: " + Environment.getExternalStorageDirectory());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
useNewPermissions = true;
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
storagePermission = true;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationPermission = true;
}
}
// Check storage permissions if marshmallow or newer
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
(ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
if (!(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE) && (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)))) {
if (useNewPermissions && (!storagePermission || !locationPermission)) {
if (!storagePermission && !locationPermission) {
String permissionRationales = getResources().getString(R.string.storage_permission_rationale) + "\n" + getResources().getString(R.string.location_permission_rationale);
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), permissionRationales,
Snackbar.LENGTH_INDEFINITE)
@ -229,14 +242,14 @@ public class ShareActivity
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(ShareActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION}, 1);
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION}, 3);
}
});
snackbar.show();
View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(3);
} else if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
} else if (!storagePermission) {
Snackbar.make(findViewById(android.R.id.content), R.string.storage_permission_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
@ -246,34 +259,83 @@ public class ShareActivity
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
}).show();
} else if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
} else if (!locationPermission) {
Snackbar.make(findViewById(android.R.id.content), R.string.location_permission_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(ShareActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 2);
}
}).show();
}
} else {
// Convert image Uri to file path
String filePath = FileUtils.getPath(this, mediaUri);
Log.d(TAG, "Filepath: " + filePath);
} else if (useNewPermissions && storagePermission && !locationPermission) {
getFileMetadata();
} else if(!useNewPermissions || (storagePermission && locationPermission)) {
getFileMetadata();
getLocationData();
}
}
// Check location permissions if marshmallow or newer
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
// 1 = Storage
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getFileMetadata();
}
return;
}
// 2 = Location
case 2: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLocationData();
}
return;
}
// 3 = Storage + Location
case 3: {
if (grantResults.length > 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getFileMetadata();
}
if (grantResults.length > 1
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
getLocationData();
}
}
}
}
public void getFileMetadata() {
filePath = FileUtils.getPath(this, mediaUri);
Log.d(TAG, "Filepath: " + filePath);
Log.d(TAG, "Calling GPSExtractor");
imageObj = new GPSExtractor(filePath, this);
imageObj.registerLocationManager();
if (filePath != null && !filePath.equals("")) {
// Gets image coords if exist, otherwise gets last known coords
String decimalCoords = imageObj.getCoords();
// Gets image coords from exif data
decimalCoords = imageObj.getCoords(false);
useImageCoords();
}
}
if (decimalCoords != null) {
public void getLocationData() {
if(imageObj == null) {
imageObj = new GPSExtractor(filePath, this);
}
decimalCoords = imageObj.getCoords(true);
useImageCoords();
}
public void useImageCoords() {
if(decimalCoords != null) {
Log.d(TAG, "Decimal coords of image: " + decimalCoords);
// Only set cache for this point if image has coords
@ -300,14 +362,10 @@ public class ShareActivity
}
}
}
}
}
}
@Override
public void onPause() {
super.onPause();
try {
imageObj.unregisterLocationManager();
Log.d(TAG, "Unregistered locationManager");

View file

@ -150,7 +150,7 @@
<string name="menu_refresh">Refresh</string>
<string name="storage_permission_rationale">Recommended: Storage for photo metadata</string>
<string name="location_permission_rationale">Optional: Location for geo-tag</string>
<string name="location_permission_rationale">Optional: Current location for category suggestions</string>
<string name="ok">OK</string>
<string name="back">Back</string>
</resources>