action view: fixed opening file media content
This commit is contained in:
parent
f5b38d2e3f
commit
23997d1f4f
4 changed files with 23 additions and 19 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -293,10 +293,14 @@ 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
|
||||
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
|
||||
return getVolumePath(context, anyPath)?.let { convertDirPathToTreeUri(context, it) }?.let { getDocumentFileFromVolumeTree(context, it, anyPath) }
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue