mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 12:53:55 +01:00
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:
parent
6adf78bec9
commit
d5278f0c85
3 changed files with 121 additions and 60 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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,60 +259,106 @@ 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) {
|
||||||
Log.d(TAG, "Calling GPSExtractor");
|
switch (requestCode) {
|
||||||
imageObj = new GPSExtractor(filePath, this);
|
// 1 = Storage
|
||||||
imageObj.registerLocationManager();
|
case 1: {
|
||||||
|
if (grantResults.length > 0
|
||||||
if (filePath != null && !filePath.equals("")) {
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
// Gets image coords if exist, otherwise gets last known coords
|
getFileMetadata();
|
||||||
String decimalCoords = imageObj.getCoords();
|
|
||||||
|
|
||||||
if (decimalCoords != null) {
|
|
||||||
Log.d(TAG, "Decimal coords of image: " + decimalCoords);
|
|
||||||
|
|
||||||
// Only set cache for this point if image has coords
|
|
||||||
if (imageObj.imageCoordsExists) {
|
|
||||||
double decLongitude = imageObj.getDecLongitude();
|
|
||||||
double decLatitude = imageObj.getDecLatitude();
|
|
||||||
app.cacheData.setQtPoint(decLongitude, decLatitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
MwVolleyApi apiCall = new MwVolleyApi(this);
|
|
||||||
|
|
||||||
List displayCatList = app.cacheData.findCategory();
|
|
||||||
boolean catListEmpty = displayCatList.isEmpty();
|
|
||||||
|
|
||||||
// If no categories found in cache, call MediaWiki API to match image coords with nearby Commons categories
|
|
||||||
if (catListEmpty) {
|
|
||||||
cacheFound = false;
|
|
||||||
apiCall.request(decimalCoords);
|
|
||||||
Log.d(TAG, "displayCatList size 0, calling MWAPI" + displayCatList.toString());
|
|
||||||
} else {
|
|
||||||
cacheFound = true;
|
|
||||||
Log.d(TAG, "Cache found, setting categoryList in MwVolleyApi to " + displayCatList.toString());
|
|
||||||
MwVolleyApi.setGpsCat(displayCatList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (filePath != null && !filePath.equals("")) {
|
||||||
|
// Gets image coords from exif data
|
||||||
|
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) {
|
||||||
|
Log.d(TAG, "Decimal coords of image: " + decimalCoords);
|
||||||
|
|
||||||
|
// Only set cache for this point if image has coords
|
||||||
|
if (imageObj.imageCoordsExists) {
|
||||||
|
double decLongitude = imageObj.getDecLongitude();
|
||||||
|
double decLatitude = imageObj.getDecLatitude();
|
||||||
|
app.cacheData.setQtPoint(decLongitude, decLatitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
MwVolleyApi apiCall = new MwVolleyApi(this);
|
||||||
|
|
||||||
|
List displayCatList = app.cacheData.findCategory();
|
||||||
|
boolean catListEmpty = displayCatList.isEmpty();
|
||||||
|
|
||||||
|
// If no categories found in cache, call MediaWiki API to match image coords with nearby Commons categories
|
||||||
|
if (catListEmpty) {
|
||||||
|
cacheFound = false;
|
||||||
|
apiCall.request(decimalCoords);
|
||||||
|
Log.d(TAG, "displayCatList size 0, calling MWAPI" + displayCatList.toString());
|
||||||
|
} else {
|
||||||
|
cacheFound = true;
|
||||||
|
Log.d(TAG, "Cache found, setting categoryList in MwVolleyApi to " + displayCatList.toString());
|
||||||
|
MwVolleyApi.setGpsCat(displayCatList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -307,7 +366,6 @@ 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");
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue