From afc58696a271261f5817beec1f569605b5be26d8 Mon Sep 17 00:00:00 2001 From: ViscousPot Date: Mon, 12 May 2025 10:33:41 +0100 Subject: [PATCH 1/5] Update FileUtils.kt --- .../mr/flutter/plugin/filepicker/FileUtils.kt | 77 ++++++++++++++++++- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt index 79edfc5b..52d6a19e 100644 --- a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt +++ b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt @@ -7,6 +7,7 @@ import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri import android.os.Build +import android.database.Cursor import android.os.Bundle import android.os.Environment import android.os.Parcelable @@ -70,11 +71,11 @@ object FileUtils { var uri = processUri(activity, data.data!!, compressionQuality) if (type == "dir") { - uri = DocumentsContract.buildDocumentUriUsingTree( + var docUriTree = DocumentsContract.buildDocumentUriUsingTree( uri, DocumentsContract.getTreeDocumentId(uri) ) - val dirPath = getFullPathFromTreeUri(uri, activity) + val dirPath = getFullPathFromTreeUri(uri, docUriTree, activity) if (dirPath != null) { finishWithSuccess(dirPath) } else { @@ -162,7 +163,6 @@ object FileUtils { putExtra(Intent.EXTRA_MIME_TYPES, it.toTypedArray()) } } - } @@ -407,6 +407,14 @@ object FileUtils { private fun isDownloadsDocument(uri: Uri): Boolean { return uri.authority == "com.android.providers.downloads.documents" } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is in External Storage Documents. + */ + fun isExternalStorageDocument(uri: Uri): Boolean { + return uri.authority == "com.android.externalstorage.documents" + } @JvmStatic fun clearCache(context: Context): Boolean { @@ -506,13 +514,74 @@ object FileUtils { return "${Environment.getExternalStorageDirectory()}/${parts.last()}" } + private fun isGooglePhotosUri(uri: Uri): Boolean { + return "com.google.android.apps.photos.content" == uri.authority + } + + private fun getDataColumn( + context: Context, + uri: Uri?, + selection: String?, + selectionArgs: Array? + ): String { + var cursor: Cursor? = null + val column = "_data" + val projection = arrayOf(column) + + try { + cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null) + if (cursor != null && cursor.moveToFirst()) { + val index = cursor.getColumnIndexOrThrow(column) + return cursor.getString(index) + } + } finally { + cursor?.close() + } + + return "" + } + @JvmStatic - fun getFullPathFromTreeUri(treeUri: Uri?, con: Context): String? { + fun getFullPathFromTreeUri(uri: Uri, treeUri: Uri?, con: Context): String? { if (treeUri == null) { return null } + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { + if ("content".equals(treeUri.scheme, ignoreCase = true)) { + return when { + isGooglePhotosUri(treeUri) -> uri.lastPathSegment ?: "" + else -> getDataColumn(con, treeUri, null, null) + } + } + + if ("file".equals(treeUri.scheme, ignoreCase = true)) { + return treeUri.path ?: "" + } + } + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { + if (isExternalStorageDocument(treeUri)) { + val docId = DocumentsContract.getDocumentId(treeUri) + val split = docId.split(":") + val type = split[0] + + if ((Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q && "home".equals(type, ignoreCase = true)) || "primary".equals(type, ignoreCase = true)) { + return "${Environment.getExternalStorageDirectory()}/Documents/${split[1]}" + } else if ("primary".equals(type, ignoreCase = true)) { + return "${Environment.getExternalStorageDirectory()}/${split[1]}" + } else { + val externalStorageVolumes = con.getExternalFilesDirs(null) + for (externalFile in externalStorageVolumes) { + val path = externalFile.absolutePath + if (path.contains(type)) { + val subPath = path.substringBefore("/Android") + return "$subPath/${split[1]}" + } + } + } + } + if (isDownloadsDocument(treeUri)) { val docId = DocumentsContract.getDocumentId(treeUri) val extPath = From 3b837a005c20c7f15fcecaba5cdf2fd21c560088 Mon Sep 17 00:00:00 2001 From: ViscousPot Date: Thu, 15 May 2025 14:24:38 +0100 Subject: [PATCH 2/5] fix: remove kitkat specific code --- .../mr/flutter/plugin/filepicker/FileUtils.kt | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt index 52d6a19e..458375e9 100644 --- a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt +++ b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt @@ -514,52 +514,12 @@ object FileUtils { return "${Environment.getExternalStorageDirectory()}/${parts.last()}" } - private fun isGooglePhotosUri(uri: Uri): Boolean { - return "com.google.android.apps.photos.content" == uri.authority - } - - private fun getDataColumn( - context: Context, - uri: Uri?, - selection: String?, - selectionArgs: Array? - ): String { - var cursor: Cursor? = null - val column = "_data" - val projection = arrayOf(column) - - try { - cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null) - if (cursor != null && cursor.moveToFirst()) { - val index = cursor.getColumnIndexOrThrow(column) - return cursor.getString(index) - } - } finally { - cursor?.close() - } - - return "" - } - @JvmStatic fun getFullPathFromTreeUri(uri: Uri, treeUri: Uri?, con: Context): String? { if (treeUri == null) { return null } - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { - if ("content".equals(treeUri.scheme, ignoreCase = true)) { - return when { - isGooglePhotosUri(treeUri) -> uri.lastPathSegment ?: "" - else -> getDataColumn(con, treeUri, null, null) - } - } - - if ("file".equals(treeUri.scheme, ignoreCase = true)) { - return treeUri.path ?: "" - } - } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { if (isExternalStorageDocument(treeUri)) { val docId = DocumentsContract.getDocumentId(treeUri) From 7319ce87909439140c420c2f883ca812397a3bee Mon Sep 17 00:00:00 2001 From: ViscousPot Date: Thu, 15 May 2025 14:29:53 +0100 Subject: [PATCH 3/5] chore: remove uri pass in --- .../kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt index 458375e9..3ac3965a 100644 --- a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt +++ b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt @@ -7,7 +7,6 @@ import android.graphics.Bitmap import android.graphics.BitmapFactory import android.net.Uri import android.os.Build -import android.database.Cursor import android.os.Bundle import android.os.Environment import android.os.Parcelable @@ -71,11 +70,11 @@ object FileUtils { var uri = processUri(activity, data.data!!, compressionQuality) if (type == "dir") { - var docUriTree = DocumentsContract.buildDocumentUriUsingTree( + uri = DocumentsContract.buildDocumentUriUsingTree( uri, DocumentsContract.getTreeDocumentId(uri) ) - val dirPath = getFullPathFromTreeUri(uri, docUriTree, activity) + val dirPath = getFullPathFromTreeUri(uri, activity) if (dirPath != null) { finishWithSuccess(dirPath) } else { @@ -515,7 +514,7 @@ object FileUtils { } @JvmStatic - fun getFullPathFromTreeUri(uri: Uri, treeUri: Uri?, con: Context): String? { + fun getFullPathFromTreeUri(treeUri: Uri?, con: Context): String? { if (treeUri == null) { return null } From 1600ffc2aa0c387cd79ae1e209035dcf8054278d Mon Sep 17 00:00:00 2001 From: ViscousPot Date: Thu, 15 May 2025 14:30:17 +0100 Subject: [PATCH 4/5] Update FileUtils.kt --- .../main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt index 3ac3965a..7c020928 100644 --- a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt +++ b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt @@ -162,6 +162,7 @@ object FileUtils { putExtra(Intent.EXTRA_MIME_TYPES, it.toTypedArray()) } } + } From e3c9d7c5673a1fecabd1487069bed78df3372f5b Mon Sep 17 00:00:00 2001 From: ViscousPot Date: Thu, 15 May 2025 14:30:34 +0100 Subject: [PATCH 5/5] Update FileUtils.kt --- .../main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt index 7c020928..c519c068 100644 --- a/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt +++ b/android/src/main/kotlin/com/mr/flutter/plugin/filepicker/FileUtils.kt @@ -162,7 +162,7 @@ object FileUtils { putExtra(Intent.EXTRA_MIME_TYPES, it.toTypedArray()) } } - + }