Fix date time issue for google photos (#2438)

This commit is contained in:
Vivek Maskara 2019-02-12 16:47:06 +05:30 committed by Josephine Lim
parent d86a3aad79
commit 2bc0d41748
9 changed files with 62 additions and 59 deletions

View file

@ -7,7 +7,6 @@ import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -18,6 +17,7 @@ import javax.inject.Singleton;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.filepicker.DefaultCallback; import fr.free.nrw.commons.filepicker.DefaultCallback;
import fr.free.nrw.commons.filepicker.FilePicker; import fr.free.nrw.commons.filepicker.FilePicker;
import fr.free.nrw.commons.filepicker.UploadableFile;
import fr.free.nrw.commons.kvstore.BasicKvStore; import fr.free.nrw.commons.kvstore.BasicKvStore;
import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.nearby.Place; import fr.free.nrw.commons.nearby.Place;
@ -116,7 +116,7 @@ public class ContributionController {
} }
@Override @Override
public void onImagesPicked(@NonNull List<File> imagesFiles, FilePicker.ImageSource source, int type) { public void onImagesPicked(@NonNull List<UploadableFile> imagesFiles, FilePicker.ImageSource source, int type) {
Intent intent = handleImagesPicked(activity, imagesFiles, getSourceFromImageSource(source)); Intent intent = handleImagesPicked(activity, imagesFiles, getSourceFromImageSource(source));
activity.startActivity(intent); activity.startActivity(intent);
} }
@ -124,8 +124,8 @@ public class ContributionController {
} }
public List<UploadableFile> handleExternalImagesPicked(Activity activity, public List<UploadableFile> handleExternalImagesPicked(Activity activity,
Intent data) { Intent data) {
return getUploadableFiles(FilePicker.handleExternalImagesPicked(data, activity)); return FilePicker.handleExternalImagesPicked(data, activity);
} }
/** /**
@ -133,13 +133,12 @@ public class ContributionController {
* Attaches place object for nearby uploads * Attaches place object for nearby uploads
*/ */
private Intent handleImagesPicked(Context context, private Intent handleImagesPicked(Context context,
List<File> imagesFiles, List<UploadableFile> imagesFiles,
String source) { String source) {
ArrayList<UploadableFile> uploadableFiles = getUploadableFiles(imagesFiles);
Intent shareIntent = new Intent(context, UploadActivity.class); Intent shareIntent = new Intent(context, UploadActivity.class);
shareIntent.setAction(ACTION_INTERNAL_UPLOADS); shareIntent.setAction(ACTION_INTERNAL_UPLOADS);
shareIntent.putExtra(EXTRA_SOURCE, source); shareIntent.putExtra(EXTRA_SOURCE, source);
shareIntent.putParcelableArrayListExtra(EXTRA_FILES, uploadableFiles); shareIntent.putParcelableArrayListExtra(EXTRA_FILES, new ArrayList<>(imagesFiles));
Place place = directKvStore.getJson(PLACE_OBJECT, Place.class); Place place = directKvStore.getJson(PLACE_OBJECT, Place.class);
if (place != null) { if (place != null) {
shareIntent.putExtra(PLACE_OBJECT, place); shareIntent.putExtra(PLACE_OBJECT, place);
@ -148,15 +147,6 @@ public class ContributionController {
return shareIntent; return shareIntent;
} }
@NonNull
private ArrayList<UploadableFile> getUploadableFiles(List<File> imagesFiles) {
ArrayList<UploadableFile> uploadableFiles = new ArrayList<>();
for (File file : imagesFiles) {
uploadableFiles.add(new UploadableFile(file));
}
return uploadableFiles;
}
/** /**
* Get image upload source * Get image upload source
*/ */

View file

@ -289,20 +289,20 @@ public class FilePicker implements Constants {
} }
@Nullable @Nullable
private static File takenCameraPicture(Context context) throws IOException, URISyntaxException { private static UploadableFile takenCameraPicture(Context context) throws IOException, URISyntaxException {
String lastCameraPhoto = PreferenceManager.getDefaultSharedPreferences(context).getString(KEY_LAST_CAMERA_PHOTO, null); String lastCameraPhoto = PreferenceManager.getDefaultSharedPreferences(context).getString(KEY_LAST_CAMERA_PHOTO, null);
if (lastCameraPhoto != null) { if (lastCameraPhoto != null) {
return new File(lastCameraPhoto); return new UploadableFile(new File(lastCameraPhoto));
} else { } else {
return null; return null;
} }
} }
@Nullable @Nullable
private static File takenCameraVideo(Context context) throws IOException, URISyntaxException { private static UploadableFile takenCameraVideo(Context context) throws IOException, URISyntaxException {
String lastCameraPhoto = PreferenceManager.getDefaultSharedPreferences(context).getString(KEY_LAST_CAMERA_VIDEO, null); String lastCameraPhoto = PreferenceManager.getDefaultSharedPreferences(context).getString(KEY_LAST_CAMERA_VIDEO, null);
if (lastCameraPhoto != null) { if (lastCameraPhoto != null) {
return new File(lastCameraPhoto); return new UploadableFile(new File(lastCameraPhoto));
} else { } else {
return null; return null;
} }
@ -343,7 +343,7 @@ public class FilePicker implements Constants {
} }
} }
public static List<File> handleExternalImagesPicked(Intent data, Activity activity) { public static List<UploadableFile> handleExternalImagesPicked(Intent data, Activity activity) {
try { try {
return getFilesFromGalleryPictures(data, activity); return getFilesFromGalleryPictures(data, activity);
} catch (IOException e) { } catch (IOException e) {
@ -406,7 +406,7 @@ public class FilePicker implements Constants {
private static void onPictureReturnedFromDocuments(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) { private static void onPictureReturnedFromDocuments(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) {
try { try {
Uri photoPath = data.getData(); Uri photoPath = data.getData();
File photoFile = PickedFiles.pickedExistingPicture(activity, photoPath); UploadableFile photoFile = PickedFiles.pickedExistingPicture(activity, photoPath);
callbacks.onImagesPicked(singleFileList(photoFile), FilePicker.ImageSource.DOCUMENTS, restoreType(activity)); callbacks.onImagesPicked(singleFileList(photoFile), FilePicker.ImageSource.DOCUMENTS, restoreType(activity));
if (configuration(activity).shouldCopyPickedImagesToPublicGalleryAppFolder()) { if (configuration(activity).shouldCopyPickedImagesToPublicGalleryAppFolder()) {
@ -420,7 +420,7 @@ public class FilePicker implements Constants {
private static void onPictureReturnedFromGallery(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) { private static void onPictureReturnedFromGallery(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) {
try { try {
List<File> files = getFilesFromGalleryPictures(data, activity); List<UploadableFile> files = getFilesFromGalleryPictures(data, activity);
callbacks.onImagesPicked(files, FilePicker.ImageSource.GALLERY, restoreType(activity)); callbacks.onImagesPicked(files, FilePicker.ImageSource.GALLERY, restoreType(activity));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -428,20 +428,20 @@ public class FilePicker implements Constants {
} }
} }
private static List<File> getFilesFromGalleryPictures(Intent data, Activity activity) throws IOException { private static List<UploadableFile> getFilesFromGalleryPictures(Intent data, Activity activity) throws IOException {
List<File> files = new ArrayList<>(); List<UploadableFile> files = new ArrayList<>();
ClipData clipData = null; ClipData clipData = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
clipData = data.getClipData(); clipData = data.getClipData();
} }
if (clipData == null) { if (clipData == null) {
Uri uri = data.getData(); Uri uri = data.getData();
File file = PickedFiles.pickedExistingPicture(activity, uri); UploadableFile file = PickedFiles.pickedExistingPicture(activity, uri);
files.add(file); files.add(file);
} else { } else {
for (int i = 0; i < clipData.getItemCount(); i++) { for (int i = 0; i < clipData.getItemCount(); i++) {
Uri uri = clipData.getItemAt(i).getUri(); Uri uri = clipData.getItemAt(i).getUri();
File file = PickedFiles.pickedExistingPicture(activity, uri); UploadableFile file = PickedFiles.pickedExistingPicture(activity, uri);
files.add(file); files.add(file);
} }
} }
@ -460,8 +460,8 @@ public class FilePicker implements Constants {
revokeWritePermission(activity, Uri.parse(lastImageUri)); revokeWritePermission(activity, Uri.parse(lastImageUri));
} }
File photoFile = FilePicker.takenCameraPicture(activity); UploadableFile photoFile = FilePicker.takenCameraPicture(activity);
List<File> files = new ArrayList<>(); List<UploadableFile> files = new ArrayList<>();
files.add(photoFile); files.add(photoFile);
if (photoFile == null) { if (photoFile == null) {
@ -493,8 +493,8 @@ public class FilePicker implements Constants {
revokeWritePermission(activity, Uri.parse(lastVideoUri)); revokeWritePermission(activity, Uri.parse(lastVideoUri));
} }
File photoFile = FilePicker.takenCameraVideo(activity); UploadableFile photoFile = FilePicker.takenCameraVideo(activity);
List<File> files = new ArrayList<>(); List<UploadableFile> files = new ArrayList<>();
files.add(photoFile); files.add(photoFile);
if (photoFile == null) { if (photoFile == null) {
@ -545,7 +545,7 @@ public class FilePicker implements Constants {
public interface Callbacks { public interface Callbacks {
void onImagePickerError(Exception e, FilePicker.ImageSource source, int type); void onImagePickerError(Exception e, FilePicker.ImageSource source, int type);
void onImagesPicked(@NonNull List<File> imageFiles, FilePicker.ImageSource source, int type); void onImagesPicked(@NonNull List<UploadableFile> imageFiles, FilePicker.ImageSource source, int type);
void onCanceled(FilePicker.ImageSource source, int type); void onCanceled(FilePicker.ImageSource source, int type);
} }

View file

@ -55,13 +55,14 @@ class PickedFiles implements Constants {
writeToFile(in, dst); writeToFile(in, dst);
} }
static void copyFilesInSeparateThread(final Context context, final List<File> filesToCopy) { static void copyFilesInSeparateThread(final Context context, final List<UploadableFile> filesToCopy) {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
List<File> copiedFiles = new ArrayList<>(); List<File> copiedFiles = new ArrayList<>();
int i = 1; int i = 1;
for (File fileToCopy : filesToCopy) { for (UploadableFile uploadableFile : filesToCopy) {
File fileToCopy = uploadableFile.getFile();
File dstDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), getFolderName(context)); File dstDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), getFolderName(context));
if (!dstDir.exists()) dstDir.mkdirs(); if (!dstDir.exists()) dstDir.mkdirs();
@ -84,8 +85,8 @@ class PickedFiles implements Constants {
}).run(); }).run();
} }
static List<File> singleFileList(File file) { static List<UploadableFile> singleFileList(UploadableFile file) {
List<File> list = new ArrayList<>(); List<UploadableFile> list = new ArrayList<>();
list.add(file); list.add(file);
return list; return list;
} }
@ -106,13 +107,13 @@ class PickedFiles implements Constants {
}); });
} }
static File pickedExistingPicture(@NonNull Context context, Uri photoUri) throws IOException { static UploadableFile pickedExistingPicture(@NonNull Context context, Uri photoUri) throws IOException {
InputStream pictureInputStream = context.getContentResolver().openInputStream(photoUri); InputStream pictureInputStream = context.getContentResolver().openInputStream(photoUri);
File directory = tempImageDirectory(context); File directory = tempImageDirectory(context);
File photoFile = new File(directory, UUID.randomUUID().toString() + "." + getMimeType(context, photoUri)); File photoFile = new File(directory, UUID.randomUUID().toString() + "." + getMimeType(context, photoUri));
photoFile.createNewFile(); photoFile.createNewFile();
writeToFile(pictureInputStream, photoFile); writeToFile(pictureInputStream, photoFile);
return photoFile; return new UploadableFile(photoUri, photoFile);
} }
static File getCameraPicturesLocation(@NonNull Context context) throws IOException { static File getCameraPicturesLocation(@NonNull Context context) throws IOException {

View file

@ -1,6 +1,5 @@
package fr.free.nrw.commons.contributions; package fr.free.nrw.commons.filepicker;
import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
@ -23,16 +22,29 @@ public class UploadableFile implements Parcelable {
return new UploadableFile[size]; return new UploadableFile[size];
} }
}; };
private final Uri contentUri;
private final File file; private final File file;
public UploadableFile(File file) { public UploadableFile(Uri contentUri, File file) {
this.contentUri = contentUri;
this.file = file; this.file = file;
} }
public UploadableFile(File file) {
this.file = file;
this.contentUri = Uri.parse(file.getAbsolutePath());
}
public UploadableFile(Parcel in) { public UploadableFile(Parcel in) {
this.contentUri = in.readParcelable(Uri.class.getClassLoader());
file = (File) in.readSerializable(); file = (File) in.readSerializable();
} }
public File getFile() {
return file;
}
public String getFilePath() { public String getFilePath() {
return file.getPath(); return file.getPath();
} }
@ -50,11 +62,6 @@ public class UploadableFile implements Parcelable {
return 0; return 0;
} }
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeSerializable(file);
}
/** /**
* Get filePath creation date from uri from all possible content providers * Get filePath creation date from uri from all possible content providers
* *
@ -62,8 +69,7 @@ public class UploadableFile implements Parcelable {
*/ */
public long getFileCreatedDate(Context context) { public long getFileCreatedDate(Context context) {
try { try {
ContentResolver contentResolver = context.getContentResolver(); Cursor cursor = context.getContentResolver().query(contentUri, null, null, null, null);
Cursor cursor = contentResolver.query(getMediaUri(), null, null, null, null);
if (cursor == null) { if (cursor == null) {
return -1;//Could not fetch last_modified return -1;//Could not fetch last_modified
} }
@ -74,7 +80,7 @@ public class UploadableFile implements Parcelable {
} }
//If both the content providers do not give the data, lets leave it to Jesus //If both the content providers do not give the data, lets leave it to Jesus
if (lastModifiedColumnIndex == -1) { if (lastModifiedColumnIndex == -1) {
return -1L; return -1l;
} }
cursor.moveToFirst(); cursor.moveToFirst();
return cursor.getLong(lastModifiedColumnIndex); return cursor.getLong(lastModifiedColumnIndex);
@ -82,4 +88,10 @@ public class UploadableFile implements Parcelable {
return -1;////Could not fetch last_modified return -1;////Could not fetch last_modified
} }
} }
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeParcelable(contentUri, 0);
parcel.writeSerializable(file);
}
} }

View file

@ -54,7 +54,7 @@ import fr.free.nrw.commons.category.CategoriesModel;
import fr.free.nrw.commons.category.CategoryItem; import fr.free.nrw.commons.category.CategoryItem;
import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.contributions.ContributionController; import fr.free.nrw.commons.contributions.ContributionController;
import fr.free.nrw.commons.contributions.UploadableFile; import fr.free.nrw.commons.filepicker.UploadableFile;
import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.nearby.Place; import fr.free.nrw.commons.nearby.Place;
@ -62,7 +62,6 @@ import fr.free.nrw.commons.theme.BaseActivity;
import fr.free.nrw.commons.utils.DialogUtil; import fr.free.nrw.commons.utils.DialogUtil;
import fr.free.nrw.commons.utils.NetworkUtils; import fr.free.nrw.commons.utils.NetworkUtils;
import fr.free.nrw.commons.utils.PermissionUtils; import fr.free.nrw.commons.utils.PermissionUtils;
import fr.free.nrw.commons.utils.StringUtils;
import fr.free.nrw.commons.utils.ViewUtil; import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
@ -73,8 +72,6 @@ import timber.log.Timber;
import static fr.free.nrw.commons.contributions.Contribution.SOURCE_EXTERNAL; import static fr.free.nrw.commons.contributions.Contribution.SOURCE_EXTERNAL;
import static fr.free.nrw.commons.contributions.ContributionController.ACTION_INTERNAL_UPLOADS; import static fr.free.nrw.commons.contributions.ContributionController.ACTION_INTERNAL_UPLOADS;
import static fr.free.nrw.commons.upload.UploadService.EXTRA_FILES; import static fr.free.nrw.commons.upload.UploadService.EXTRA_FILES;
import static fr.free.nrw.commons.utils.ImageUtils.Result;
import static fr.free.nrw.commons.utils.ImageUtils.getErrorMessageForResult;
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT; import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
public class UploadActivity extends BaseActivity implements UploadView, SimilarImageInterface { public class UploadActivity extends BaseActivity implements UploadView, SimilarImageInterface {

View file

@ -19,8 +19,8 @@ import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.contributions.UploadableFile;
import fr.free.nrw.commons.filepicker.MimeTypeMapWrapper; import fr.free.nrw.commons.filepicker.MimeTypeMapWrapper;
import fr.free.nrw.commons.filepicker.UploadableFile;
import fr.free.nrw.commons.kvstore.BasicKvStore; import fr.free.nrw.commons.kvstore.BasicKvStore;
import fr.free.nrw.commons.nearby.Place; import fr.free.nrw.commons.nearby.Place;
import fr.free.nrw.commons.settings.Prefs; import fr.free.nrw.commons.settings.Prefs;
@ -100,6 +100,7 @@ public class UploadModel {
SimilarImageInterface similarImageInterface) { SimilarImageInterface similarImageInterface) {
fileProcessor.initFileDetails(Objects.requireNonNull(uploadableFile.getFilePath()), context.getContentResolver()); fileProcessor.initFileDetails(Objects.requireNonNull(uploadableFile.getFilePath()), context.getContentResolver());
long fileCreatedDate = uploadableFile.getFileCreatedDate(context); long fileCreatedDate = uploadableFile.getFileCreatedDate(context);
Timber.d("File created date is %d", fileCreatedDate);
GPSExtractor gpsExtractor = fileProcessor.processFileCoordinates(similarImageInterface); GPSExtractor gpsExtractor = fileProcessor.processFileCoordinates(similarImageInterface);
return new UploadItem(Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate); return new UploadItem(Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate);
} }
@ -283,8 +284,11 @@ public class UploadModel {
contribution.setTag("mimeType", item.mimeType); contribution.setTag("mimeType", item.mimeType);
contribution.setSource(item.source); contribution.setSource(item.source);
contribution.setContentProviderUri(item.mediaUri); contribution.setContentProviderUri(item.mediaUri);
Timber.d("Created timestamp while building contribution is %s, %s",
item.getCreatedTimestamp(),
new Date(item.getCreatedTimestamp()));
if (item.createdTimestamp != -1L) { if (item.createdTimestamp != -1L) {
contribution.setDateCreated(new Date(item.createdTimestamp)); contribution.setDateCreated(new Date(item.getCreatedTimestamp()));
//Set the date only if you have it, else the upload service is gonna try it the other way //Set the date only if you have it, else the upload service is gonna try it the other way
} }
return contribution; return contribution;

View file

@ -6,7 +6,6 @@ import android.content.Context;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@ -15,7 +14,7 @@ import javax.inject.Singleton;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.category.CategoriesModel; import fr.free.nrw.commons.category.CategoriesModel;
import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.contributions.UploadableFile; import fr.free.nrw.commons.filepicker.UploadableFile;
import fr.free.nrw.commons.kvstore.BasicKvStore; import fr.free.nrw.commons.kvstore.BasicKvStore;
import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.nearby.Place; import fr.free.nrw.commons.nearby.Place;

View file

@ -3,7 +3,7 @@ package fr.free.nrw.commons.upload
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import fr.free.nrw.commons.auth.SessionManager import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.contributions.UploadableFile import fr.free.nrw.commons.filepicker.UploadableFile
import fr.free.nrw.commons.kvstore.BasicKvStore import fr.free.nrw.commons.kvstore.BasicKvStore
import fr.free.nrw.commons.mwapi.MediaWikiApi import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.nearby.Place import fr.free.nrw.commons.nearby.Place

View file

@ -1,6 +1,6 @@
package fr.free.nrw.commons.upload package fr.free.nrw.commons.upload
import fr.free.nrw.commons.contributions.UploadableFile import fr.free.nrw.commons.filepicker.UploadableFile
import fr.free.nrw.commons.mwapi.MediaWikiApi import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.nearby.Place import fr.free.nrw.commons.nearby.Place
import io.reactivex.Observable import io.reactivex.Observable