parent
1c6cb52269
commit
fe8948ef5e
1 changed files with 45 additions and 7 deletions
|
@ -225,18 +225,53 @@ class MediaStoreImageProvider : ImageProvider() {
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun hasEntry(context: Context, contentUri: Uri): Boolean {
|
||||||
|
var found = false
|
||||||
|
val projection = arrayOf(MediaStore.MediaColumns._ID)
|
||||||
|
try {
|
||||||
|
val cursor = context.contentResolver.query(contentUri, projection, null, null, null)
|
||||||
|
if (cursor != null) {
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
cursor.close()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(LOG_TAG, "failed to get entry at contentUri=$contentUri", e)
|
||||||
|
}
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
private fun needSize(mimeType: String) = MimeTypes.SVG != mimeType
|
private fun needSize(mimeType: String) = MimeTypes.SVG != mimeType
|
||||||
|
|
||||||
// `uri` is a media URI, not a document URI
|
// `uri` is a media URI, not a document URI
|
||||||
override suspend fun delete(activity: Activity, uri: Uri, path: String?, mimeType: String) {
|
override suspend fun delete(activity: Activity, uri: Uri, path: String?, mimeType: String) {
|
||||||
path ?: throw Exception("failed to delete file because path is null")
|
path ?: throw Exception("failed to delete file because path is null")
|
||||||
|
|
||||||
|
// the following situations are possible:
|
||||||
|
// - there is an entry in the Media Store and there is a file on storage
|
||||||
|
// - there is an entry in the Media Store but there is no longer a file on storage
|
||||||
|
// - there is no entry in the Media Store but there is a file on storage
|
||||||
val file = File(path)
|
val file = File(path)
|
||||||
if (file.exists()) {
|
val fileExists = file.exists()
|
||||||
|
|
||||||
|
if (fileExists) {
|
||||||
if (StorageUtils.canEditByFile(activity, path)) {
|
if (StorageUtils.canEditByFile(activity, path)) {
|
||||||
Log.d(LOG_TAG, "delete file at uri=$uri path=$path")
|
if (hasEntry(activity, uri)) {
|
||||||
if (file.delete()) {
|
Log.d(LOG_TAG, "delete content at uri=$uri path=$path")
|
||||||
scanObsoletePath(activity, path, mimeType)
|
activity.contentResolver.delete(uri, null, null)
|
||||||
|
}
|
||||||
|
// in theory, deleting via content resolver should remove the file on storage
|
||||||
|
// in practice, the file may still be there afterwards
|
||||||
|
if (file.exists()) {
|
||||||
|
Log.d(LOG_TAG, "delete file at uri=$uri path=$path")
|
||||||
|
if (file.delete()) {
|
||||||
|
// in theory, scanning an obsolete path should remove the entry from the Media Store
|
||||||
|
// in practice, the entry may still be there afterwards
|
||||||
|
scanObsoletePath(activity, path, mimeType)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if (!isMediaUriPermissionGranted(activity, uri, mimeType)
|
} else if (!isMediaUriPermissionGranted(activity, uri, mimeType)
|
||||||
|
@ -245,7 +280,7 @@ class MediaStoreImageProvider : ImageProvider() {
|
||||||
// if the file is on SD card, calling the content resolver `delete()`
|
// if the file is on SD card, calling the content resolver `delete()`
|
||||||
// removes the entry from the Media Store but it doesn't delete the file,
|
// removes the entry from the Media Store but it doesn't delete the file,
|
||||||
// even when the app has the permission, so we manually delete the document file
|
// even when the app has the permission, so we manually delete the document file
|
||||||
Log.d(LOG_TAG, "delete document at uri=$uri path=$path")
|
Log.d(LOG_TAG, "delete document (fileExists=$fileExists) at uri=$uri path=$path")
|
||||||
val df = StorageUtils.getDocumentFile(activity, path, uri)
|
val df = StorageUtils.getDocumentFile(activity, path, uri)
|
||||||
|
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
|
@ -258,9 +293,12 @@ class MediaStoreImageProvider : ImageProvider() {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log.d(LOG_TAG, "delete content at uri=$uri path=$path")
|
Log.d(LOG_TAG, "delete content (fileExists=$fileExists) at uri=$uri path=$path")
|
||||||
if (activity.contentResolver.delete(uri, null, null) > 0) return
|
if (activity.contentResolver.delete(uri, null, null) > 0) return
|
||||||
throw Exception("failed to delete row from content provider")
|
|
||||||
|
if (hasEntry(activity, uri) || file.exists()) {
|
||||||
|
throw Exception("failed to delete row from content provider")
|
||||||
|
}
|
||||||
} catch (securityException: SecurityException) {
|
} catch (securityException: SecurityException) {
|
||||||
// even if the app has access permission granted on the containing directory,
|
// even if the app has access permission granted on the containing directory,
|
||||||
// the delete request may yield a `RecoverableSecurityException` on Android 10+
|
// the delete request may yield a `RecoverableSecurityException` on Android 10+
|
||||||
|
|
Loading…
Reference in a new issue