diff --git a/.changeset/gold-readers-eat.md b/.changeset/gold-readers-eat.md new file mode 100644 index 00000000..72d2fa72 --- /dev/null +++ b/.changeset/gold-readers-eat.md @@ -0,0 +1,5 @@ +--- +'@capawesome/capacitor-file-picker': minor +--- + +feat(android): add persistent ContentUrl functionality to pickFile diff --git a/package-lock.json b/package-lock.json index f5c6896d..0241d063 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6149,7 +6149,7 @@ }, "packages/cloudinary": { "name": "@capawesome/capacitor-cloudinary", - "version": "5.0.0", + "version": "5.1.0", "funding": [ { "type": "github", @@ -6194,7 +6194,7 @@ }, "packages/datetime-picker": { "name": "@capawesome-team/capacitor-datetime-picker", - "version": "5.0.0", + "version": "5.1.1", "funding": [ { "type": "github", @@ -6280,7 +6280,7 @@ }, "packages/file-opener": { "name": "@capawesome-team/capacitor-file-opener", - "version": "5.0.2", + "version": "5.0.3", "funding": [ { "type": "github", @@ -6366,7 +6366,7 @@ }, "packages/file-picker": { "name": "@capawesome/capacitor-file-picker", - "version": "5.1.0", + "version": "5.1.1", "funding": [ { "type": "github", diff --git a/packages/file-picker/README.md b/packages/file-picker/README.md index 50b9d661..a6a05fb2 100644 --- a/packages/file-picker/README.md +++ b/packages/file-picker/README.md @@ -264,11 +264,12 @@ Remove all listeners for this plugin. #### PickFilesOptions -| Prop | Type | Description | Default | -| -------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| **`types`** | string[] | List of accepted file types. Look at [IANA Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml) for a complete list of standard media types. This option cannot be used with `multiple: true` on Android. | | -| **`multiple`** | boolean | Whether multiple files may be selected. | false | -| **`readData`** | boolean | Whether to read the file data. | false | +| Prop | Type | Description | Default | Since | +| ----------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- | +| **`persistContentUri`** | boolean | Request persistent file access for reusing received path after app restart or system reboot. Only available on Android, iOS paths are persistent by default. | false | 5.1.2 | +| **`types`** | string[] | List of accepted file types. Look at [IANA Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml) for a complete list of standard media types. This option cannot be used with `multiple: true` on Android. | | | +| **`multiple`** | boolean | Whether multiple files may be selected. | false | | +| **`readData`** | boolean | Whether to read the file data. | false | | #### PickMediaOptions diff --git a/packages/file-picker/android/src/main/java/io/capawesome/capacitorjs/plugins/filepicker/FilePickerPlugin.java b/packages/file-picker/android/src/main/java/io/capawesome/capacitorjs/plugins/filepicker/FilePickerPlugin.java index 08e90d3b..3ce165db 100644 --- a/packages/file-picker/android/src/main/java/io/capawesome/capacitorjs/plugins/filepicker/FilePickerPlugin.java +++ b/packages/file-picker/android/src/main/java/io/capawesome/capacitorjs/plugins/filepicker/FilePickerPlugin.java @@ -1,6 +1,7 @@ package io.capawesome.capacitorjs.plugins.filepicker; import android.app.Activity; +import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; import android.util.Log; @@ -16,6 +17,7 @@ import com.getcapacitor.annotation.CapacitorPlugin; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import org.json.JSONException; @CapacitorPlugin(name = "FilePicker") @@ -39,11 +41,13 @@ public void convertHeicToJpeg(PluginCall call) { @PluginMethod public void pickFiles(PluginCall call) { try { + boolean persistContentUri = call.getBoolean("persistContentUri", false); + String intentAction = persistContentUri ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_GET_CONTENT; JSArray types = call.getArray("types", null); boolean multiple = call.getBoolean("multiple", false); String[] parsedTypes = parseTypesOption(types); - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + Intent intent = new Intent(intentAction); intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multiple); @@ -139,11 +143,12 @@ private void pickFilesResult(PluginCall call, ActivityResult result) { if (call == null) { return; } + boolean persistContentUri = call.getBoolean("persistContentUri", false); boolean readData = call.getBoolean("readData", false); int resultCode = result.getResultCode(); switch (resultCode) { case Activity.RESULT_OK: - JSObject callResult = createPickFilesResult(result.getData(), readData); + JSObject callResult = createPickFilesResult(result.getData(), persistContentUri, readData); call.resolve(callResult); break; case Activity.RESULT_CANCELED: @@ -159,7 +164,8 @@ private void pickFilesResult(PluginCall call, ActivityResult result) { } } - private JSObject createPickFilesResult(@Nullable Intent data, boolean readData) { + private JSObject createPickFilesResult(@Nullable Intent data, boolean persistContentUri, boolean readData) { + ContentResolver contentResolver = getContext().getContentResolver(); JSObject callResult = new JSObject(); List filesResultList = new ArrayList<>(); if (data == null) { @@ -181,6 +187,9 @@ private JSObject createPickFilesResult(@Nullable Intent data, boolean readData) if (uri == null) { continue; } + if (persistContentUri) { + contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); + } JSObject fileResult = new JSObject(); if (readData) { fileResult.put("data", implementation.getDataFromUri(uri)); diff --git a/packages/file-picker/src/definitions.ts b/packages/file-picker/src/definitions.ts index a6f004c4..d36e41ad 100644 --- a/packages/file-picker/src/definitions.ts +++ b/packages/file-picker/src/definitions.ts @@ -91,6 +91,15 @@ export interface ConvertHeicToJpegResult { } export interface PickFilesOptions { + /** + * Request persistent file access for reusing received path after app restart or system reboot. + * + * Only available on Android, iOS paths are persistent by default. + * + * @since 5.1.2 + * @default false + */ + persistContentUri?: boolean; /** * List of accepted file types. * Look at [IANA Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml) for a complete list of standard media types.