From f10d9229b238b01a628a22035f4bfffe3e6b96e6 Mon Sep 17 00:00:00 2001 From: honjow Date: Fri, 11 Nov 2022 23:58:06 +0800 Subject: [PATCH] add openDocument --- .../storageaccessframework/DocumentFileApi.kt | 51 +++++++++++++++++++ .../lib/StorageAccessFrameworkConstant.kt | 2 + lib/src/saf/saf.dart | 20 ++++++++ 3 files changed, 73 insertions(+) diff --git a/android/src/main/kotlin/io/alexrintt/sharedstorage/storageaccessframework/DocumentFileApi.kt b/android/src/main/kotlin/io/alexrintt/sharedstorage/storageaccessframework/DocumentFileApi.kt index 5f1bc30..895b93d 100644 --- a/android/src/main/kotlin/io/alexrintt/sharedstorage/storageaccessframework/DocumentFileApi.kt +++ b/android/src/main/kotlin/io/alexrintt/sharedstorage/storageaccessframework/DocumentFileApi.kt @@ -60,6 +60,10 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) : result.notSupported(call.method, API_21) } } + OPEN_DOCUMENT -> + if (Build.VERSION.SDK_INT >= API_21) { + openDocument(call, result) + } OPEN_DOCUMENT_TREE -> if (Build.VERSION.SDK_INT >= API_21) { openDocumentTree(call, result) @@ -250,6 +254,33 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) : } } + @RequiresApi(API_21) + private fun openDocument(call: MethodCall, result: MethodChannel.Result) { + + val initialUri = call.argument("initialUri") + + val intent = + Intent(Intent.ACTION_OPEN_DOCUMENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + + if (initialUri != null) { + val tree = DocumentFile.fromTreeUri(plugin.context, Uri.parse(initialUri)) + if (Build.VERSION.SDK_INT >= API_26) { + putExtra(DocumentsContract.EXTRA_INITIAL_URI, tree?.uri) + } + } + + type = call.argument("mimeType") ?: "*/*" + putExtra(Intent.EXTRA_ALLOW_MULTIPLE, call.argument("multiple") ?: false) + } + + if (pendingResults[OPEN_DOCUMENT_CODE] != null) return + + pendingResults[OPEN_DOCUMENT_CODE] = Pair(call, result) + + plugin.binding?.activity?.startActivityForResult(intent, OPEN_DOCUMENT_CODE) + } + @RequiresApi(API_21) private fun openDocumentTree(call: MethodCall, result: MethodChannel.Result) { val grantWritePermission = call.argument("grantWritePermission")!! @@ -394,6 +425,26 @@ internal class DocumentFileApi(private val plugin: SharedStoragePlugin) : pendingResults.remove(OPEN_DOCUMENT_TREE_CODE) } } + OPEN_DOCUMENT_CODE -> { + val pendingResult = pendingResults[OPEN_DOCUMENT_CODE] ?: return false + + try { + // if data.clipData not null, uriList from data.clipData, else uriList is data.data + val uriList = data?.clipData?.let { + (0 until it.itemCount).map { i -> it.getItemAt(i).uri } + } ?: data?.data?.let { listOf(it) } + + if (uriList != null) { + pendingResult.second.success(uriList.map { "$it" }) + + return true + } + + pendingResult.second.success(null) + } finally { + pendingResults.remove(OPEN_DOCUMENT_CODE) + } + } } return false diff --git a/android/src/main/kotlin/io/alexrintt/sharedstorage/storageaccessframework/lib/StorageAccessFrameworkConstant.kt b/android/src/main/kotlin/io/alexrintt/sharedstorage/storageaccessframework/lib/StorageAccessFrameworkConstant.kt index 41d1de4..ad61abf 100644 --- a/android/src/main/kotlin/io/alexrintt/sharedstorage/storageaccessframework/lib/StorageAccessFrameworkConstant.kt +++ b/android/src/main/kotlin/io/alexrintt/sharedstorage/storageaccessframework/lib/StorageAccessFrameworkConstant.kt @@ -19,6 +19,7 @@ const val DOCUMENTS_CONTRACT_EXTRA_INITIAL_URI = /** * Available DocumentFile Method Channel APIs */ +const val OPEN_DOCUMENT = "openDocument" const val OPEN_DOCUMENT_TREE = "openDocumentTree" const val PERSISTED_URI_PERMISSIONS = "persistedUriPermissions" const val RELEASE_PERSISTABLE_URI_PERMISSION = "releasePersistableUriPermission" @@ -54,3 +55,4 @@ const val GET_DOCUMENT_CONTENT = "getDocumentContent" * Intent Request Codes */ const val OPEN_DOCUMENT_TREE_CODE = 10 +const val OPEN_DOCUMENT_CODE = 11 diff --git a/lib/src/saf/saf.dart b/lib/src/saf/saf.dart index 7357c21..3d7accd 100644 --- a/lib/src/saf/saf.dart +++ b/lib/src/saf/saf.dart @@ -35,6 +35,26 @@ Future openDocumentTree({ return selectedDirectoryUri?.apply((e) => Uri.parse(e)); } +/// [Refer to details](https://developer.android.com/reference/android/content/Intent#ACTION_OPEN_DOCUMENT). +Future?> openDocument({ + Uri? initialUri, + String mimeType = '*/*', + bool multiple = false, +}) async { + const kOpenDocument = 'openDocument'; + + final args = { + if (initialUri != null) 'initialUri': '$initialUri', + 'mimeType': mimeType, + 'multiple': multiple, + }; + + final selectedUriList = + await kDocumentFileChannel.invokeListMethod(kOpenDocument, args); + + return selectedUriList?.apply((e) => e.map((e) => Uri.parse(e as String)).toList()); +} + /// {@template sharedstorage.saf.persistedUriPermissions} /// Returns an `List` with all persisted [Uri] ///