Merge pull request #1644 from misaochan/fix-automatic-location

Remove current location retrieval from upload process entirely
This commit is contained in:
Vivek Maskara 2018-07-07 22:50:41 +05:30 committed by GitHub
commit 2d831c089d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 23 additions and 189 deletions

View file

@ -106,20 +106,20 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
ParcelFileDescriptor descriptor = contentResolver.openFileDescriptor(mediaUri, "r");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (descriptor != null) {
imageObj = new GPSExtractor(descriptor.getFileDescriptor(), context, prefs);
imageObj = new GPSExtractor(descriptor.getFileDescriptor());
}
} else {
String filePath = getPathOfMediaOrCopy();
if (filePath != null) {
imageObj = new GPSExtractor(filePath, context, prefs);
imageObj = new GPSExtractor(filePath);
}
}
decimalCoords = imageObj.getCoords(gpsEnabled);
decimalCoords = imageObj.getCoords();
if (decimalCoords == null || !imageObj.imageCoordsExists) {
//Find other photos taken around the same time which has gps coordinates
if (!haveCheckedForOtherImages)
findOtherImages(gpsEnabled);// Do not do repeat the process
findOtherImages();// Do not do repeat the process
} else {
useImageCoords();
}
@ -137,9 +137,8 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
/**
* Find other images around the same location that were taken within the last 20 sec
*
* @param gpsEnabled True if GPS is enabled
*/
private void findOtherImages(boolean gpsEnabled) {
private void findOtherImages() {
Timber.d("filePath" + getPathOfMediaOrCopy());
long timeOfCreation = new File(filePath).lastModified();//Time when the original image was created
@ -161,17 +160,17 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (descriptor != null) {
tempImageObj = new GPSExtractor(descriptor.getFileDescriptor(), context, prefs);
tempImageObj = new GPSExtractor(descriptor.getFileDescriptor());
}
} else {
if (filePath != null) {
tempImageObj = new GPSExtractor(file.getAbsolutePath(), context, prefs);
tempImageObj = new GPSExtractor(file.getAbsolutePath());
}
}
if (tempImageObj != null) {
Timber.d("not null fild EXIF" + tempImageObj.imageCoordsExists + " coords" + tempImageObj.getCoords(gpsEnabled));
if (tempImageObj.getCoords(gpsEnabled) != null && tempImageObj.imageCoordsExists) {
Timber.d("not null fild EXIF" + tempImageObj.imageCoordsExists + " coords" + tempImageObj.getCoords());
if (tempImageObj.getCoords() != null && tempImageObj.imageCoordsExists) {
// Current image has gps coordinates and it's not current gps locaiton
Timber.d("This file has image coords:" + file.getAbsolutePath());
SimilarImageDialogFragment newFragment = new SimilarImageDialogFragment();
@ -250,7 +249,7 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
@Override
public void onPositiveResponse() {
imageObj = tempImageObj;
decimalCoords = imageObj.getCoords(false);// Not necessary to use gps as image already ha EXIF data
decimalCoords = imageObj.getCoords();// Not necessary to use gps as image already ha EXIF data
Timber.d("EXIF from tempImageObj");
useImageCoords();
}

View file

@ -1,13 +1,6 @@
package fr.free.nrw.commons.upload;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.ExifInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
@ -19,31 +12,21 @@ import timber.log.Timber;
/**
* Extracts geolocation to be passed to API for category suggestions. If a picture with geolocation
* is uploaded, extract latitude and longitude from EXIF data of image. If a picture without
* geolocation is uploaded, retrieve user's location (if enabled in Settings).
* is uploaded, extract latitude and longitude from EXIF data of image.
*/
public class GPSExtractor {
private final Context context;
private SharedPreferences prefs;
private ExifInterface exif;
private double decLatitude;
private double decLongitude;
private Double currentLatitude = null;
private Double currentLongitude = null;
public boolean imageCoordsExists;
private MyLocationListener myLocationListener;
private LocationManager locationManager;
/**
* Construct from the file descriptor of the image (only for API 24 or newer).
* @param fileDescriptor the file descriptor of the image
* @param context the context
*/
@RequiresApi(24)
public GPSExtractor(@NonNull FileDescriptor fileDescriptor, Context context, SharedPreferences prefs) {
this.context = context;
this.prefs = prefs;
public GPSExtractor(@NonNull FileDescriptor fileDescriptor) {
try {
exif = new ExifInterface(fileDescriptor);
} catch (IOException | IllegalArgumentException e) {
@ -54,65 +37,22 @@ public class GPSExtractor {
/**
* Construct from the file path of the image.
* @param path file path of the image
* @param context the context
*
*/
public GPSExtractor(@NonNull String path, Context context, SharedPreferences prefs) {
this.prefs = prefs;
public GPSExtractor(@NonNull String path) {
try {
exif = new ExifInterface(path);
} catch (IOException | IllegalArgumentException e) {
Timber.w(e);
}
this.context = context;
}
/**
* Check if user enabled retrieval of their current location in Settings
* @return true if enabled, false if disabled
*/
private boolean gpsPreferenceEnabled() {
boolean gpsPref = prefs.getBoolean("allowGps", false);
Timber.d("Gps pref set to: %b", gpsPref);
return gpsPref;
}
/**
* Registers a LocationManager to listen for current location
*/
protected void registerLocationManager() {
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
myLocationListener = new MyLocationListener();
try {
locationManager.requestLocationUpdates(provider, 400, 1, myLocationListener);
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
myLocationListener.onLocationChanged(location);
}
} catch (IllegalArgumentException e) {
Timber.e(e, "Illegal argument exception");
} catch (SecurityException e) {
Timber.e(e, "Security exception");
}
}
protected void unregisterLocationManager() {
try {
locationManager.removeUpdates(myLocationListener);
} catch (SecurityException e) {
Timber.e(e, "Security exception");
}
}
/**
* Extracts geolocation (either of image from EXIF data, or of user)
* @param useGPS set to true if location permissions allowed (by API 23), false if disallowed
* @return coordinates as string (needs to be passed as a String in API query)
*/
@Nullable
public String getCoords(boolean useGPS) {
public String getCoords() {
String latitude;
String longitude;
String latitudeRef;
@ -120,30 +60,9 @@ public class GPSExtractor {
String decimalCoords;
//If image has no EXIF data and user has enabled GPS setting, get user's location
//TODO: Always return null as a temporary fix for #1599
if (exif == null || exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) == null) {
if (useGPS) {
registerLocationManager();
imageCoordsExists = false;
Timber.d("EXIF data has no location info");
//Check what user's preference is for automatic location detection
boolean gpsPrefEnabled = gpsPreferenceEnabled();
//Check that currentLatitude and currentLongitude have been
// explicitly set by MyLocationListener
// and do not default to (0.0,0.0)
if (gpsPrefEnabled && currentLatitude != null && currentLongitude != null) {
Timber.d("Current location values: Lat = %f Long = %f",
currentLatitude, currentLongitude);
return String.valueOf(currentLatitude) + "|" + String.valueOf(currentLongitude);
} else {
// No coords found
return null;
}
} else {
return null;
}
return null;
} else {
//If image has EXIF data, extract image coords
imageCoordsExists = true;
@ -166,33 +85,6 @@ public class GPSExtractor {
}
}
/**
* Listen for user's location when it changes
*/
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Timber.d("%s's status changed to %d", provider, status);
}
@Override
public void onProviderEnabled(String provider) {
Timber.d("Provider %s enabled", provider);
}
@Override
public void onProviderDisabled(String provider) {
Timber.d("Provider %s disabled", provider);
}
}
public double getDecLatitude() {
return decLatitude;
}

View file

@ -329,18 +329,18 @@ public class MultipleShareActivity extends AuthenticatedActivity
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(imageUri,"r");
if (fd != null) {
gpsExtractor = new GPSExtractor(fd.getFileDescriptor(),this,prefs);
gpsExtractor = new GPSExtractor(fd.getFileDescriptor());
}
} else {
String filePath = FileUtils.getPath(this,imageUri);
if (filePath != null) {
gpsExtractor = new GPSExtractor(filePath,this,prefs);
gpsExtractor = new GPSExtractor(filePath);
}
}
if (gpsExtractor != null) {
//get image coordinates from exif data or user location
return gpsExtractor.getCoords(locationPermitted);
return gpsExtractor.getCoords();
}
} catch (FileNotFoundException fnfe) {

View file

@ -21,9 +21,7 @@ import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.MenuItem;
import android.view.View;
@ -64,7 +62,6 @@ import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.utils.ViewUtil;
import timber.log.Timber;
import android.support.design.widget.FloatingActionButton;
import static fr.free.nrw.commons.upload.ExistingFileAsync.Result.DUPLICATE_PROCEED;
import static fr.free.nrw.commons.upload.ExistingFileAsync.Result.NO_DUPLICATE;
import static fr.free.nrw.commons.upload.FileUtils.getSHA1;
@ -78,7 +75,6 @@ public class ShareActivity
extends AuthenticatedActivity
implements SingleUploadFragment.OnUploadActionInitiated,
OnCategoriesSaveHandler {
private static final int REQUEST_PERM_ON_CREATE_LOCATION = 2;
private static final int REQUEST_PERM_ON_SUBMIT_STORAGE = 4;
//Had to make them class variables, to extract out the click listeners, also I see no harm in this
final Rect startBounds = new Rect();
@ -131,7 +127,6 @@ public class ShareActivity
private String title;
private String description;
private String wikiDataEntityId;
private Snackbar snackbar;
private boolean duplicateCheckPassed = false;
private boolean isNearbyUpload = false;
private Animator CurrentAnimator;
@ -276,22 +271,6 @@ public class ShareActivity
Timber.d("Uri: %s", mediaUri.toString());
Timber.d("Ext storage dir: %s", Environment.getExternalStorageDirectory());
useNewPermissions = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
useNewPermissions = true;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationPermitted = true;
}
}
// Check location permissions if M or newer for category suggestions, request via snackbar if not present
if (!locationPermitted) {
requestPermissionUsingSnackBar(
getString(R.string.location_permission_rationale),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERM_ON_CREATE_LOCATION);
}
SingleUploadFragment shareView = (SingleUploadFragment) getSupportFragmentManager().findFragmentByTag("shareView");
categorizationFragment = (CategorizationFragment) getSupportFragmentManager().findFragmentByTag("categorization");
if (shareView == null && categorizationFragment == null) {
@ -392,7 +371,7 @@ public class ShareActivity
}
/**
* Handles BOTH snackbar permission request (for location) and submit button permission request (for storage)
* Handles submit button permission request (for storage)
*
* @param requestCode type of request
* @param permissions permissions requested
@ -401,41 +380,19 @@ public class ShareActivity
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_PERM_ON_CREATE_LOCATION: {
if (grantResults.length >= 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationPermitted = true;
checkIfFileExists();
}
return;
}
// Storage (from submit button) - this needs to be separate from (1) because only the
// submit button should bring user to next screen
case REQUEST_PERM_ON_SUBMIT_STORAGE: {
if (grantResults.length >= 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//It is OK to call this at both (1) and (4) because if perm had been granted at
//snackbar, user should not be prompted at submit button
checkIfFileExists();
//Uploading only begins if storage permission granted from arrow icon
uploadBegins();
snackbar.dismiss();
}
}
}
}
/**
* Displays Snackbar to ask for location permissions
*/
private Snackbar requestPermissionUsingSnackBar(String rationale, final String[] perms, final int code) {
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), rationale,
Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok,
view -> ActivityCompat.requestPermissions(ShareActivity.this, perms, code));
snackbar.show();
return snackbar;
}
/**
* Check if file user wants to upload already exists on Commons
*/
@ -472,12 +429,6 @@ public class ShareActivity
@Override
public void onPause() {
super.onPause();
try {
gpsObj.unregisterLocationManager();
Timber.d("Unregistered locationManager");
} catch (NullPointerException e) {
Timber.d("locationManager does not exist, not unregistered");
}
}
@Override

View file

@ -38,16 +38,8 @@
</PreferenceCategory>
<PreferenceCategory
android:title="@string/preference_category_location">
<SwitchPreference
android:key="allowGps"
android:title="@string/allow_gps"
android:defaultValue="false"
android:summary="@string/allow_gps_summary" />
</PreferenceCategory>
<!-- The key 'allowGps' was used before and has since been removed based on the discussion at #1599.
Do not reuse this key unless you revive the same feature with the changes mentioned at #1599.-->
<PreferenceCategory
android:title="@string/preference_category_feedback">