diff --git a/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt b/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt index bb0a371e1..a7e3a671d 100644 --- a/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt +++ b/app/src/main/java/fr/free/nrw/commons/filepicker/FilePicker.kt @@ -296,10 +296,19 @@ object FilePicker : Constants { * https://github.com/commons-app/apps-android-commons/issues/6357 */ private fun takePersistableUriPermissions(context: Context, result: ActivityResult) { - result.data?.data?.also { uri -> - val takeFlags: Int = (Intent.FLAG_GRANT_READ_URI_PERMISSION - or Intent.FLAG_GRANT_WRITE_URI_PERMISSION) - context.contentResolver.takePersistableUriPermission(uri, takeFlags) + result.data?.let { intentData -> + val takeFlags: Int = (Intent.FLAG_GRANT_READ_URI_PERMISSION) + // Persist the URI permission for all URIs in the clip data + // if multiple images are selected, + // or for the single URI if only one image is selected + intentData.clipData?.let { clipData -> + for (i in 0 until clipData.itemCount) { + context.contentResolver.takePersistableUriPermission( + clipData.getItemAt(i).uri, takeFlags) + } + } ?: intentData.data?.let { uri -> + context.contentResolver.takePersistableUriPermission(uri, takeFlags) + } } } @@ -358,6 +367,7 @@ object FilePicker : Constants { callbacks: Callbacks ) { if (result.resultCode == Activity.RESULT_OK && !isPhoto(result.data)) { + takePersistableUriPermissions(activity, result) try { val files = getFilesFromGalleryPictures(result.data, activity) callbacks.onImagesPicked(files, ImageSource.GALLERY, restoreType(activity)) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/ImageProcessingService.kt b/app/src/main/java/fr/free/nrw/commons/upload/ImageProcessingService.kt index 98f5042a7..cbec7559f 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/ImageProcessingService.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/ImageProcessingService.kt @@ -128,33 +128,10 @@ class ImageProcessingService @Inject constructor( * @return IMAGE_DUPLICATE or IMAGE_OK */ fun checkIfFileAlreadyExists(originalFilePath: Uri, modifiedFilePath: Uri): Single { - // Safely open the original (picker) URI. If permission is gone after app restart, - // skip this leg and proceed with the modified file check to avoid crashing. - val originalCheck: Single = - Single.fromCallable { appContext.contentResolver.openInputStream(originalFilePath) } - .flatMap { inputStream -> - if (inputStream != null) checkDuplicateImage(inputStream) else Single.just(IMAGE_OK) - } - .onErrorReturn { t -> - Timber.w(t, "Skipping original URI duplicate check (no permission or not found)") - IMAGE_OK - } - .subscribeOn(Schedulers.io()) - - // Safely open the modified file stream as well; be defensive in case the temp/cached file - // was cleaned up while the app was backgrounded. - val modifiedCheck: Single = - Single.fromCallable { fileUtilsWrapper.getFileInputStream(modifiedFilePath.path) } - .flatMap { inputStream -> - if (inputStream != null) checkDuplicateImage(inputStream) else Single.just(IMAGE_OK) - } - .onErrorReturn { t -> - Timber.w(t, "Skipping modified file duplicate check (file missing)") - IMAGE_OK - } - .subscribeOn(Schedulers.io()) - - return Single.zip(originalCheck, modifiedCheck) { resultForOriginal, resultForDuplicate -> + return Single.zip( + checkDuplicateImage(inputStream = appContext.contentResolver.openInputStream(originalFilePath)!!), + checkDuplicateImage(inputStream = fileUtilsWrapper.getFileInputStream(modifiedFilePath.path)) + ) { resultForOriginal, resultForDuplicate -> return@zip if (resultForOriginal == IMAGE_DUPLICATE || resultForDuplicate == IMAGE_DUPLICATE) IMAGE_DUPLICATE else IMAGE_OK } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt b/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt index 587f05a1f..58ffefe73 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt @@ -434,6 +434,12 @@ class UploadWorker( makeWikiDataEdit(uploadResult, contribution) } showSuccessNotification(contribution) + if (appContext.contentResolver.persistedUriPermissions.any { + it.uri == contribution.contentUri }) { + appContext.contentResolver.releasePersistableUriPermission( + contribution.contentUri!!, Intent.FLAG_GRANT_READ_URI_PERMISSION + ) + } } else { Timber.e("Stash Upload failed") showFailedNotification(contribution)