action view: fixed opening file media content

This commit is contained in:
Thibault Deckers 2021-03-19 14:35:26 +09:00
parent f5b38d2e3f
commit 23997d1f4f
4 changed files with 23 additions and 19 deletions

View file

@ -2,6 +2,8 @@
All notable changes to this project will be documented in this file.
## [Unreleased]
### Fixed
- opening media shared by other apps as file media content
## [v1.3.6] - 2021-03-18
### Added

View file

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

View file

@ -8,7 +8,6 @@ import android.media.MediaExtractor
import android.media.MediaFormat
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.util.Log
import androidx.exifinterface.media.ExifInterface
@ -684,9 +683,7 @@ class MetadataHandler(private val context: Context) : MethodCallHandler {
isVideo(mimeType) -> ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id)
else -> uri
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentUri = MediaStore.setRequireOriginal(contentUri)
}
contentUri = StorageUtils.getOriginalUri(contentUri)
}
}

View file

@ -293,9 +293,13 @@ object StorageUtils {
// need a document URI (not a media content URI) to open a `DocumentFile` output stream
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isMediaStoreContentUri(mediaUri)) {
// cleanest API to get it
val docUri = MediaStore.getDocumentUri(context, mediaUri)
if (docUri != null) {
return DocumentFileCompat.fromSingleUri(context, docUri)
try {
val docUri = MediaStore.getDocumentUri(context, mediaUri)
if (docUri != null) {
return DocumentFileCompat.fromSingleUri(context, docUri)
}
} catch (e: Exception) {
Log.w(LOG_TAG, "failed to get document URI for mediaUri=$mediaUri", e)
}
}
// fallback for older APIs
@ -401,13 +405,21 @@ object StorageUtils {
return ContentResolver.SCHEME_CONTENT.equals(uri.scheme, ignoreCase = true) && MediaStore.AUTHORITY.equals(uri.host, ignoreCase = true)
}
fun openInputStream(context: Context, uri: Uri): InputStream? {
var effectiveUri = uri
fun getOriginalUri(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)) {
effectiveUri = MediaStore.setRequireOriginal(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)
}
}
return uri
}
fun openInputStream(context: Context, uri: Uri): InputStream? {
val effectiveUri = getOriginalUri(uri)
return try {
context.contentResolver.openInputStream(effectiveUri)
} catch (e: FileNotFoundException) {
@ -420,12 +432,7 @@ object StorageUtils {
}
fun openMetadataRetriever(context: Context, uri: Uri): MediaMetadataRetriever? {
var effectiveUri = 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)) {
effectiveUri = MediaStore.setRequireOriginal(uri)
}
val effectiveUri = getOriginalUri(uri)
return try {
MediaMetadataRetriever().apply {
setDataSource(context, effectiveUri)