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

View file

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

View file

@ -150,7 +150,7 @@
<string name="menu_refresh">Refresh</string> <string name="menu_refresh">Refresh</string>
<string name="storage_permission_rationale">Recommended: Storage for photo metadata</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="ok">OK</string>
<string name="back">Back</string> <string name="back">Back</string>
</resources> </resources>