Fix urgent crashes A and E (#1749)

* Create utility class for contribution process

* implement method to save five from given URİ

* Add file utilities for directory checks

* Add ContributionUtils for saving file during upload

* Change method call acordingly with handleImagePicked() method

* Call method to save file temproarily when a photo to upload is chosen from contributions list.

* Call method to save file temproarily when a photo to upload is chosen from nearby list and map

* Arrange method call

* Write a method to save file temporarily during upload process. It will save the file to a internal path and it will be deleted by another method after upload process is done.

* Add a method to save a file to a given path from a content provider Uri

* On openAssetFileDescriptor method, use URi from temporarily saved file, instead of Contributions.getLocalUri which was Uri from content provider

* Edit uploadContribution method so that it will use FileInputStream from temporarily saved file, insdeat of the Uri from content provider.

* Make it work

* Code cleanup

* Add directory cleaner method

* Call temp directory cleaner method at the end of uplpoad process

* Use FileInputStream insted

* Add directory cleaner method

* Add file removal method

* Use external directory instead

* Make destination file name flexible

* Make it work with share action coming from another activity

* Make it work for Multiple hare Activity

* Code cleanup

* Solve camera issue

* Fix camera crash

* Cleanup

* Revert change of commenting out posibly useles code, because I am not sure if it is useless or not. Requires discussion

* Use timestamp in temoorary file names, so that we wont never create same file and access old file reference. It was a weird problem though

* Code cleanup

* Add nullable annotation to handleImagePicked method uri parameter

* Add Nullable anotation to method

* Code cleanup

* Bugfix: use uri.getPath() instead uri.toString

* Remove unecesarry file saving operation, which was added accidentally

* Fix travis fail

* Remove temp file if upload gets failed and file is still there

* Code cleanup:Remove unused parameters from removeTempFile method

* Empty temp directory on app create, in case some of files are still there

* Add null check to array to prevent NPE on first run

* Fix multiple uploads bug

* Remove file if upload is succeed

* Add external storage utility methods

* Check external file permission before saving files temporarily

* finish activity if permission is not granted

* Add log lines

* Remove files even if user decides to go back without sharing

* Add easy null check

* Change storage permission settings in singe upload fragment too

* Finish app if permission is not granted

* Code optimisation

* Remove temp file if upload process never is finalised on activity stop

* Bugfix maybe contribution is never created

* Fix travis build
This commit is contained in:
neslihanturan 2018-08-01 23:24:08 +03:00 committed by Josephine Lim
parent 22d2b1795c
commit d29aa2e2e5
18 changed files with 440 additions and 66 deletions

View file

@ -46,6 +46,7 @@ public class Contribution extends Media {
private String decimalCoords;
private boolean isMultiple;
private String wikiDataEntityId;
private Uri contentProviderUri;
public Contribution(Uri contentUri, String filename, Uri localUri, String imageUrl, Date timestamp,
int state, long dataLength, Date dateUploaded, long transferred,
@ -236,4 +237,12 @@ public class Contribution extends Media {
public void setWikiDataEntityId(String wikiDataEntityId) {
this.wikiDataEntityId = wikiDataEntityId;
}
public void setContentProviderUri(Uri contentProviderUri) {
this.contentProviderUri = contentProviderUri;
}
public Uri getContentProviderUri() {
return contentProviderUri;
}
}

View file

@ -7,9 +7,11 @@ import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.FileProvider;
import android.util.Log;
import java.io.File;
import java.util.Date;
@ -28,8 +30,8 @@ import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ENTITY_ID_
public class ContributionController {
private static final int SELECT_FROM_GALLERY = 1;
private static final int SELECT_FROM_CAMERA = 2;
public static final int SELECT_FROM_GALLERY = 1;
public static final int SELECT_FROM_CAMERA = 2;
private Fragment fragment;
@ -91,8 +93,7 @@ public class ContributionController {
fragment.startActivityForResult(pickImageIntent, SELECT_FROM_GALLERY);
}
public void handleImagePicked(int requestCode, Intent data, boolean isDirectUpload, String wikiDataEntityId) {
Timber.d("Is direct upload %s and the Wikidata entity ID is %s", isDirectUpload, wikiDataEntityId);
public void handleImagePicked(int requestCode, @Nullable Uri uri, boolean isDirectUpload, String wikiDataEntityId) {
FragmentActivity activity = fragment.getActivity();
Timber.d("handleImagePicked() called with onActivityResult()");
Intent shareIntent = new Intent(activity, ShareActivity.class);
@ -100,7 +101,7 @@ public class ContributionController {
switch (requestCode) {
case SELECT_FROM_GALLERY:
//Handles image picked from gallery
Uri imageData = data.getData();
Uri imageData = uri;
shareIntent.setType(activity.getContentResolver().getType(imageData));
shareIntent.putExtra(EXTRA_STREAM, imageData);
shareIntent.putExtra(EXTRA_SOURCE, SOURCE_GALLERY);

View file

@ -38,6 +38,7 @@ import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.quiz.QuizChecker;
import fr.free.nrw.commons.settings.Prefs;
import fr.free.nrw.commons.upload.UploadService;
import fr.free.nrw.commons.utils.ContributionUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
@ -199,6 +200,9 @@ public class ContributionsActivity
Contribution c = contributionDao.fromCursor(allContributions);
if (c.getState() == STATE_FAILED) {
Timber.d("Deleting failed contrib %s", c.toString());
// If upload fails and then user decides to cancel upload at all, which means contribution
// object will be deleted. So we have to delete temp file for that contribution.
ContributionUtils.removeTemporaryFile(c.getLocalUri());
contributionDao.delete(c);
} else {
Timber.d("Skipping deletion for non-failed contrib %s", c.toString());

View file

@ -3,11 +3,13 @@ package fr.free.nrw.commons.contributions;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -31,6 +33,7 @@ import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.nearby.NearbyActivity;
import fr.free.nrw.commons.utils.ContributionUtils;
import timber.log.Timber;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
@ -117,7 +120,13 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
if (resultCode == RESULT_OK) {
Timber.d("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
requestCode, resultCode, data);
controller.handleImagePicked(requestCode, data, false, null);
if (requestCode == ContributionController.SELECT_FROM_CAMERA) {
// If coming from camera, pass null as uri. Because camera photos get saved to a
// fixed directory
controller.handleImagePicked(requestCode, null, false, null);
} else {
controller.handleImagePicked(requestCode, data.getData(), false, null);
}
} else {
Timber.e("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
requestCode, resultCode, data);