crash fix for users who somehow revoked ACCESS_MEDIA_LOCATION permission

This commit is contained in:
Thibault Deckers 2021-06-22 08:31:38 +09:00
parent 2d32b782bc
commit 62a8f05d1a
3 changed files with 12 additions and 7 deletions

View file

@ -112,7 +112,7 @@ class DebugHandler(private val context: Context) : MethodCallHandler {
isVideo(mimeType) -> ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id)
else -> uri
}
contentUri = StorageUtils.getOriginalUri(contentUri)
contentUri = StorageUtils.getOriginalUri(context, contentUri)
}
}

View file

@ -658,7 +658,7 @@ class MetadataHandler(private val context: Context) : MethodCallHandler {
isVideo(mimeType) -> ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id)
else -> uri
}
contentUri = StorageUtils.getOriginalUri(contentUri)
contentUri = StorageUtils.getOriginalUri(context, contentUri)
}
}

View file

@ -1,8 +1,10 @@
package deckers.thibault.aves.utils
import android.Manifest
import android.annotation.SuppressLint
import android.content.ContentResolver
import android.content.Context
import android.content.pm.PackageManager
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.Build
@ -399,21 +401,24 @@ object StorageUtils {
return ContentResolver.SCHEME_CONTENT.equals(uri.scheme, ignoreCase = true) && MediaStore.AUTHORITY.equals(uri.host, ignoreCase = true)
}
fun getOriginalUri(uri: Uri): Uri {
fun getOriginalUri(context: Context, uri: Uri): Uri {
// we get a permission denial if we require original from a provider other than the media store
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && isMediaStoreContentUri(uri)) {
val path = uri.path
path ?: return uri
// from Android R, accessing the original URI for a file media content yields a `SecurityException`
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R || path.startsWith("/external/images/") || path.startsWith("/external/video/")) {
return MediaStore.setRequireOriginal(uri)
if (path.startsWith("/external/images/") || path.startsWith("/external/video/")) {
// "Caller must hold ACCESS_MEDIA_LOCATION permission to access original"
if (context.checkSelfPermission(Manifest.permission.ACCESS_MEDIA_LOCATION) == PackageManager.PERMISSION_GRANTED) {
return MediaStore.setRequireOriginal(uri)
}
}
}
return uri
}
fun openInputStream(context: Context, uri: Uri): InputStream? {
val effectiveUri = getOriginalUri(uri)
val effectiveUri = getOriginalUri(context, uri)
return try {
context.contentResolver.openInputStream(effectiveUri)
} catch (e: FileNotFoundException) {
@ -426,7 +431,7 @@ object StorageUtils {
}
fun openMetadataRetriever(context: Context, uri: Uri): MediaMetadataRetriever? {
val effectiveUri = getOriginalUri(uri)
val effectiveUri = getOriginalUri(context, uri)
return try {
MediaMetadataRetriever().apply {
setDataSource(context, effectiveUri)