fix(mobile): resolve view intent MIME type with fallbacks

This commit is contained in:
Peter Ombodi
2026-04-27 16:28:58 +03:00
parent 7d5be4317f
commit 6b291c469e
2 changed files with 46 additions and 1 deletions
@@ -5,6 +5,10 @@ import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.provider.OpenableColumns
import android.util.Log
import android.webkit.MimeTypeMap
private const val TAG = "MediaStoreUtils"
object MediaStoreUtils {
private fun externalFilesUri(): Uri =
@@ -31,6 +35,14 @@ object MediaStoreUtils {
else -> externalFilesUri()
}
fun resolveMimeType(context: Context, uri: Uri, fallbackMimeType: String? = null): String? {
return context.contentResolver.getType(uri)
?: fallbackMimeType
?: resolveMimeTypeFromDisplayName(context, uri)
?: resolveMimeTypeFromPath(uri.path)
?: resolveMimeTypeFromPath(uri.toString())
}
fun resolveLocalIdByRelativePath(context: Context, path: String, mimeType: String): String? {
val fileName = path.substringAfterLast('/', missingDelimiterValue = path)
val parent = path.substringBeforeLast('/', "").let { if (it.isEmpty()) "" else "$it/" }
@@ -76,6 +88,39 @@ object MediaStoreUtils {
)
}
private fun resolveMimeTypeFromDisplayName(context: Context, uri: Uri): String? {
return try {
context.contentResolver.query(uri, arrayOf(OpenableColumns.DISPLAY_NAME), null, null, null)?.use { cursor ->
if (!cursor.moveToFirst()) {
return null
}
val displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
if (displayNameIndex < 0) {
return null
}
resolveMimeTypeFromPath(cursor.getString(displayNameIndex))
}
} catch (e: Exception) {
Log.w(TAG, "Failed to resolve MIME type from display name: $uri", e)
null
}
}
private fun resolveMimeTypeFromPath(path: String?): String? {
if (path.isNullOrBlank()) {
return null
}
val extension = path.substringAfterLast('.', missingDelimiterValue = "").substringBefore('?').substringBefore('#')
if (extension.isBlank()) {
return null
}
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.lowercase())
}
private fun queryLatestId(
context: Context,
tableUri: Uri,
@@ -83,7 +83,7 @@ class ViewIntentPlugin : FlutterPlugin, ActivityAware, PluginRegistry.NewIntentL
ioScope.launch {
try {
val mimeType = context.contentResolver.getType(uri)
val mimeType = MediaStoreUtils.resolveMimeType(context, uri, intent.type)
if (mimeType == null || (!mimeType.startsWith("image/") && !mimeType.startsWith("video/"))) {
callback(Result.success(null))
return@launch