diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java index 00baac847..7861f96de 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.java @@ -197,6 +197,10 @@ public class Contribution extends Media { this.localUri = localUri; } + public void setDecimalCoords(String decimalCoords) { + this.decimalCoords = decimalCoords; + } + @NonNull private String licenseTemplateFor(String license) { switch (license) { @@ -215,6 +219,7 @@ public class Contribution extends Media { case Prefs.Licenses.CC_BY_SA: return "{{self|cc-by-sa-3.0}}"; } + throw new RuntimeException("Unrecognized license value: " + license); } } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java b/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java index f069cfec9..daa2b6d09 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java @@ -3,21 +3,27 @@ package fr.free.nrw.commons.upload; import android.annotation.SuppressLint; import android.content.ContentUris; import android.content.Context; +import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Environment; +import android.os.ParcelFileDescriptor; +import android.preference.PreferenceManager; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; +import java.util.Date; +import fr.free.nrw.commons.CommonsApplication; import timber.log.Timber; public class FileUtils { @@ -91,8 +97,41 @@ public class FileUtils { // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); + } else { + //fetching path may fail depending on the source URI and all hope is lost + //so we will create and use a copy of the file, which seems to work + String copyPath = null; + try { + ParcelFileDescriptor descriptor + = context.getContentResolver().openFileDescriptor(uri, "r"); + if (descriptor != null) { + SharedPreferences sharedPref = PreferenceManager + .getDefaultSharedPreferences(context); + boolean useExtStorage = sharedPref.getBoolean("useExternalStorage", true); + if (useExtStorage) { + copyPath = Environment.getExternalStorageDirectory().toString() + + "/CommonsApp/" + new Date().getTime() + ".jpg"; + File newFile = new File(Environment.getExternalStorageDirectory().toString() + "/CommonsApp"); + newFile.mkdir(); + FileUtils.copy( + descriptor.getFileDescriptor(), + copyPath); + Timber.d("Filepath (copied): %s", copyPath); + return copyPath; + } + copyPath = context.getCacheDir().getAbsolutePath() + + "/" + new Date().getTime() + ".jpg"; + FileUtils.copy( + descriptor.getFileDescriptor(), + copyPath); + Timber.d("Filepath (copied): %s", copyPath); + return copyPath; + } + } catch (IOException e) { + Timber.w(e, "Error in file " + copyPath); + return null; + } } - return null; } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/MultipleShareActivity.java b/app/src/main/java/fr/free/nrw/commons/upload/MultipleShareActivity.java index 00a1b958f..ac0afa979 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/MultipleShareActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/MultipleShareActivity.java @@ -11,7 +11,9 @@ import android.database.DataSetObserver; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.ParcelFileDescriptor; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.app.ActivityCompat; import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; @@ -21,6 +23,7 @@ import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.Toast; +import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; @@ -69,6 +72,8 @@ public class MultipleShareActivity extends AuthenticatedActivity private MediaDetailPagerFragment mediaDetails; private CategorizationFragment categorizationFragment; + private boolean locationPermitted = false; + @Override public Media getMediaAtPosition(int i) { return photosList.get(i); @@ -213,6 +218,14 @@ public class MultipleShareActivity extends AuthenticatedActivity getSupportFragmentManager().addOnBackStackChangedListener(this); requestAuthToken(); + + //TODO: 15/10/17 should location permission be explicitly requested if not provided? + //check if location permission is enabled + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + locationPermitted = true; + } + } } @Override @@ -258,6 +271,11 @@ public class MultipleShareActivity extends AuthenticatedActivity up.setTag("sequence", i); up.setSource(Contribution.SOURCE_EXTERNAL); up.setMultiple(true); + String imageGpsCoordinates = extractImageGpsData(uri); + if (imageGpsCoordinates != null) { + Timber.d("GPS data for image found!"); + up.setDecimalCoords(imageGpsCoordinates); + } photosList.add(up); } } @@ -287,4 +305,46 @@ public class MultipleShareActivity extends AuthenticatedActivity getSupportActionBar().setDisplayHomeAsUpEnabled(mediaDetails != null && mediaDetails.isVisible()); } + /** + * Will attempt to extract the gps coordinates using exif data or by using the current + * location if available for the image who's imageUri has been provided. + * @param imageUri The uri of the image who's GPS coordinates data we wish to extract + * @return GPS coordinates as a String as is returned by {@link GPSExtractor} + */ + @Nullable + private String extractImageGpsData(Uri imageUri) { + Timber.d("Entering extractImagesGpsData"); + + if (imageUri == null) { + //now why would you do that??? + return null; + } + + GPSExtractor gpsExtractor = null; + + try { + 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); + } + } else { + String filePath = FileUtils.getPath(this,imageUri); + if (filePath != null) { + gpsExtractor = new GPSExtractor(filePath,this,prefs); + } + } + + if (gpsExtractor != null) { + //get image coordinates from exif data or user location + return gpsExtractor.getCoords(locationPermitted); + } + + } catch (FileNotFoundException fnfe) { + Timber.w(fnfe); + return null; + } + + return null; + } } \ No newline at end of file