mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Handle null URI while uploading picture (#2262)
* Handle null URI while uploading picture * Modify cache method to never return null path * Fix tests
This commit is contained in:
parent
e69c03cf83
commit
e773a82206
6 changed files with 71 additions and 36 deletions
|
|
@ -98,14 +98,27 @@ public class FileUtils {
|
|||
}
|
||||
}
|
||||
|
||||
static String createCopyPathAndCopy(boolean useExternalStorage,
|
||||
Uri uri,
|
||||
ContentResolver contentResolver,
|
||||
Context context) throws IOException {
|
||||
return useExternalStorage ? createExternalCopyPathAndCopy(uri, contentResolver) :
|
||||
createCopyPathAndCopy(uri, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* In older devices getPath() may fail depending on the source URI. Creating and using a copy of the file seems to work instead.
|
||||
*
|
||||
* @return path of copy
|
||||
*/
|
||||
@NonNull
|
||||
static String createExternalCopyPathAndCopy(Uri uri, ContentResolver contentResolver) throws IOException {
|
||||
FileDescriptor fileDescriptor = contentResolver.openFileDescriptor(uri, "r").getFileDescriptor();
|
||||
@Nullable
|
||||
private static String createExternalCopyPathAndCopy(Uri uri, ContentResolver contentResolver) throws IOException {
|
||||
ParcelFileDescriptor parcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r");
|
||||
if (parcelFileDescriptor == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
|
||||
String copyPath = Environment.getExternalStorageDirectory().toString() + "/CommonsApp/" + new Date().getTime() + "." + getFileExt(uri, contentResolver);
|
||||
File newFile = new File(Environment.getExternalStorageDirectory().toString() + "/CommonsApp");
|
||||
newFile.mkdir();
|
||||
|
|
@ -119,8 +132,8 @@ public class FileUtils {
|
|||
*
|
||||
* @return path of copy
|
||||
*/
|
||||
@NonNull
|
||||
static String createCopyPathAndCopy(Uri uri, Context context) throws IOException {
|
||||
@Nullable
|
||||
private static String createCopyPathAndCopy(Uri uri, Context context) throws IOException {
|
||||
FileDescriptor fileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r").getFileDescriptor();
|
||||
String copyPath = context.getCacheDir().getAbsolutePath() + "/" + new Date().getTime() + "." + getFileExt(uri, context.getContentResolver());
|
||||
FileUtils.copy(fileDescriptor, copyPath);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@ public class FileUtilsWrapper {
|
|||
|
||||
}
|
||||
|
||||
public String createExternalCopyPathAndCopy(Uri uri, ContentResolver contentResolver) throws IOException {
|
||||
return FileUtils.createExternalCopyPathAndCopy(uri, contentResolver);
|
||||
}
|
||||
|
||||
public String createCopyPathAndCopy(Uri uri, Context context) throws IOException {
|
||||
return FileUtils.createCopyPathAndCopy(uri, context);
|
||||
public String createCopyPathAndCopy(boolean useExtStorage,
|
||||
Uri uri,
|
||||
ContentResolver contentResolver,
|
||||
Context context) throws IOException {
|
||||
return FileUtils.createCopyPathAndCopy(useExtStorage,
|
||||
uri,
|
||||
contentResolver,
|
||||
context);
|
||||
}
|
||||
|
||||
public String getFileExt(String fileName) {
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ENTITY_ID_
|
|||
import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ITEM_LOCATION;
|
||||
|
||||
public class UploadActivity extends AuthenticatedActivity implements UploadView, SimilarImageInterface {
|
||||
@Inject InputMethodManager inputMethodManager;
|
||||
@Inject MediaWikiApi mwApi;
|
||||
@Inject @Named("direct_nearby_upload_prefs") SharedPreferences directPrefs;
|
||||
@Inject UploadPresenter presenter;
|
||||
|
|
@ -613,6 +612,10 @@ public class UploadActivity extends AuthenticatedActivity implements UploadView,
|
|||
|
||||
if (Intent.ACTION_SEND.equals(intent.getAction())) {
|
||||
Uri mediaUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
if(mediaUri == null) {
|
||||
handleNullMedia();
|
||||
return;
|
||||
}
|
||||
if (intent.getBooleanExtra("isDirectUpload", false)) {
|
||||
String imageTitle = directPrefs.getString("Title", "");
|
||||
String imageDesc = directPrefs.getString("Desc", "");
|
||||
|
|
@ -627,10 +630,24 @@ public class UploadActivity extends AuthenticatedActivity implements UploadView,
|
|||
} else if (Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) {
|
||||
ArrayList<Uri> urisList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
Timber.i("Received multiple upload %s", urisList.size());
|
||||
|
||||
if(urisList.isEmpty()) {
|
||||
handleNullMedia();
|
||||
return;
|
||||
}
|
||||
presenter.receive(urisList, mimeType, source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle null URI from the received intent.
|
||||
* Current implementation will simply show a toast and finish the upload activity.
|
||||
*/
|
||||
private void handleNullMedia() {
|
||||
ViewUtil.showLongToast(this, R.string.error_processing_image);
|
||||
finish();
|
||||
}
|
||||
|
||||
private void updateCardState(boolean state, ImageView button, View... content) {
|
||||
button.animate().rotation(button.getRotation() + (state ? 180 : -180)).start();
|
||||
if (content != null) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import fr.free.nrw.commons.settings.Prefs;
|
|||
import fr.free.nrw.commons.utils.BitmapRegionDecoderWrapper;
|
||||
import fr.free.nrw.commons.utils.ImageUtils;
|
||||
import fr.free.nrw.commons.utils.ImageUtilsWrapper;
|
||||
import fr.free.nrw.commons.utils.StringUtils;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
|
|
@ -171,6 +172,7 @@ public class UploadModel {
|
|||
|
||||
/**
|
||||
* Get file creation date from uri from all possible content providers
|
||||
*
|
||||
* @param media
|
||||
* @return
|
||||
*/
|
||||
|
|
@ -354,23 +356,25 @@ public class UploadModel {
|
|||
|
||||
/**
|
||||
* Copy files into local storage and return file path
|
||||
*
|
||||
* If somehow copy fails, it returns the original path
|
||||
* @param media Uri of the file
|
||||
* @return path of the enw file
|
||||
*/
|
||||
private String cacheFileUpload(Uri media) {
|
||||
String finalFilePath;
|
||||
try {
|
||||
String copyPath;
|
||||
if (useExtStorage)
|
||||
copyPath = fileUtilsWrapper.createExternalCopyPathAndCopy(media, contentResolver);
|
||||
else
|
||||
copyPath = fileUtilsWrapper.createCopyPathAndCopy(media, context);
|
||||
Timber.i("File path is " + copyPath);
|
||||
return copyPath;
|
||||
} catch (IOException e) {
|
||||
Timber.w(e, "Error in copying URI " + media.getPath());
|
||||
return null;
|
||||
String copyFilePath = fileUtilsWrapper.createCopyPathAndCopy(useExtStorage, media, contentResolver, context);
|
||||
Timber.i("Copied file path is %s", copyFilePath);
|
||||
finalFilePath = copyFilePath;
|
||||
} catch (Exception e) {
|
||||
Timber.w(e, "Error in copying URI %s. Using original file path instead", media.getPath());
|
||||
finalFilePath = media.getPath();
|
||||
}
|
||||
|
||||
if (StringUtils.isNullOrWhiteSpace(finalFilePath)) {
|
||||
finalFilePath = media.getPath();
|
||||
}
|
||||
return finalFilePath;
|
||||
}
|
||||
|
||||
void keepPicture() {
|
||||
|
|
|
|||
|
|
@ -450,6 +450,7 @@ Upload your first media by touching the camera or gallery icon above.</string>
|
|||
|
||||
<string name="this_function_needs_network_connection">This function requires network connection, please check your connection settings.</string>
|
||||
<string name="bad_token_error_proposed_solution">Upload failed due to issues with edit token. Please try logging out and in again. </string>
|
||||
<string name="error_processing_image">Error occurred while processing the image. Please try again!</string>
|
||||
|
||||
<plurals name="receiving_shared_content">
|
||||
<item quantity="one">Receiving shared content. Processing the image might take some time depending on the size of the image and your device</item>
|
||||
|
|
|
|||
|
|
@ -64,10 +64,8 @@ class UploadModelTest {
|
|||
|
||||
`when`(context!!.applicationContext)
|
||||
.thenReturn(mock(Application::class.java))
|
||||
`when`(fileUtilsWrapper!!.createCopyPathAndCopy(any(Uri::class.java), any(Context::class.java)))
|
||||
`when`(fileUtilsWrapper!!.createCopyPathAndCopy(anyBoolean(), any(Uri::class.java), nullable(ContentResolver::class.java), any(Context::class.java)))
|
||||
.thenReturn("file.jpg")
|
||||
`when`(fileUtilsWrapper!!.createExternalCopyPathAndCopy(any(Uri::class.java), any(ContentResolver::class.java)))
|
||||
.thenReturn("extFile.jpg")
|
||||
`when`(fileUtilsWrapper!!.getFileExt(anyString()))
|
||||
.thenReturn("jpg")
|
||||
`when`(fileUtilsWrapper!!.getSHA1(any(InputStream::class.java)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue