Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(file-picker): add pickDirectory(...) method #16

Closed
ieugen opened this issue Jan 4, 2023 · 6 comments · Fixed by #326 · May be fixed by capawesome-team/capacitor-file-picker#71
Closed

feat(file-picker): add pickDirectory(...) method #16

ieugen opened this issue Jan 4, 2023 · 6 comments · Fixed by #326 · May be fixed by capawesome-team/capacitor-file-picker#71
Assignees
Labels

Comments

@ieugen
Copy link

ieugen commented Jan 4, 2023

I would like to be able to pick a directory instead of a file.

I'm working on adding Android local storage support for organice https://github.com/200ok-ch/organice/ .
We need the ability to select the directory that contains the org files to manage.

Thanks,
Eugen

@ieugen
Copy link
Author

ieugen commented Jan 9, 2023

The solution IMO is to upgrade the API used to access files. https://developer.android.com/guide/topics/providers/document-provider#client

On Android 5.0 (API level 21) and higher, you can also use the ACTION_OPEN_DOCUMENT_TREE intent, which allows the user to choose a directory for a client app to access.

@ieugen
Copy link
Author

ieugen commented Jan 13, 2023

For this, you can use a specific intent: Intent.ACTION_OPEN_DOCUMENT_TREE .

I made this working on the organice app: 200ok-ch/organice#933
Works very good.

I am using the document library but I believe it's easier to implement the features using android code - as not to depend on the library ?!

implementation 'androidx.documentfile:documentfile:1.0.1'

There is also example on how to persist permissions across Android reboots.

    @PluginMethod
    public void pickDirectory(PluginCall call) {
        // Sample code from https://github.com/android/storage-samples/blob/main/StorageClient/Application/src/main/java/com/example/android/storageclient/StorageClientFragment.java
        // BEGIN_INCLUDE (use_open_document_intent)
        // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file browser.
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);

        // Optionally, specify a URI for the directory that should be opened in
        // the system file picker when it loads.
        // intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uriToLoad);

        // https://capacitorjs.com/docs/plugins/android#intents-with-results
        startActivityForResult(call, intent, "pickDirectoryResult");
    }

    /**
     * Companion callback to {@link OrganiceSync::pickDirectory} .
     * Handles the result of "pick a directory" action.
     * <p>
     * Will save permissions to the directory.
     *
     * @param call
     * @param result
     */
    @SuppressLint("WrongConstant")
    @ActivityCallback
    public void pickDirectoryResult(PluginCall call, ActivityResult result) {
        if (call == null) {
            return;
        }

        Intent intent = result.getData();

        if (intent != null) {
            Uri uri = intent.getData();
            JSObject ret = new JSObject();

            // Persist permissions
            // https://developer.android.com/training/data-storage/shared/documents-files#grant-access-directory
            final int takeFlags = intent.getFlags()
                    & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            // Check for the freshest data.
            getActivity().getContentResolver().takePersistableUriPermission(uri, takeFlags);

            var d = DocumentFile.fromTreeUri(getContext(),uri);

            ret.put("uri", uri);
            ret.put("path", d.getUri().getEncodedPath());
            call.resolve(ret);
        } else {
            JSObject ret = new JSObject();
            ret.put("intent", result.getData());
            ret.put("resultCode", result.getResultCode());
            ret.put("uri", null);
            call.reject("Failed with intent code " + result.getResultCode(), ret);
        }
    }

@robingenz
Copy link
Member

Thank you for your input! That will help me a lot.

@ieugen
Copy link
Author

ieugen commented Jan 13, 2023

Well, it would be great to have this working properly for Android and IOs.
If that is the case, organice should switch back to the library IMO.

We need basic operations for organice:

  • Open directory and save persmissions for future use - to use a specific directory for org files
  • list directory files with metadata: last modified, size, etc
  • read file as string
  • write file as string
  • create file (with contents)
  • create directory

@robingenz robingenz transferred this issue from capawesome-team/capacitor-file-picker Apr 1, 2023
@robingenz robingenz changed the title feat: Option to pick a directory ? feat(file-picker): Option to pick a directory ? Apr 1, 2023
@Nikita-schetko
Copy link

Guys, is there any chance that 'open directory' feature will be added for file picker ? Would be extremely nice to have

@robingenz
Copy link
Member

@Nikita-schetko Yes, but there is no ETA. PRs are welcome.

@robingenz robingenz changed the title feat(file-picker): Option to pick a directory ? feat(file-picker): add pickDirectory(...) method Feb 3, 2024
@ebarooni ebarooni linked a pull request Nov 19, 2024 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
4 participants