mozilla / geckoview

GeckoView is a set of components for embedding Gecko in Android apps
https://geckoview.dev
397 stars 48 forks source link

Implement file chooser for input type file #115

Open skoolknot opened 4 years ago

skoolknot commented 4 years ago

When I clicked input type file, nothing happen. Any idea on how to implement file chooser similar as WebChromeClient onShowFileChooser?

pocmo commented 4 years ago

You will have to provide an implementation of PromptDelegate.FilePrompt: https://mozilla.github.io/geckoview/javadoc/mozilla-central/org/mozilla/geckoview/GeckoSession.PromptDelegate.FilePrompt.html

The GeckoView example app has an implementation of it here: https://searchfox.org/mozilla-central/source/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/BasicGeckoViewPrompt.java#712-769

Our feature-prompts Android Component provides an implementation for all prompts: https://github.com/mozilla-mobile/android-components/tree/master/components/feature/prompts

skoolknot commented 4 years ago

Thanks! The file chooser is now working.

    @Override
    public void onFilePrompt(@NonNull GeckoSession session, @Nullable String title, int type, @Nullable String[] mimeTypes, @NonNull FileCallback callback) {
        mFilePathCallback = callback;

        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");

        startActivityForResult(intent, INPUT_FILE_REQUEST_CODE);
    }

However, I have problem with passing the URI back. Tried using FileCallback.confirm, but nothing happen. Here is the code.

if (data != null) {
                        Log.d(TAG, "onActivityResult: " + requestCode + " " + resultCode + " " + data);
                        Log.d(TAG, "onActivityResult: " + data.getData());
                        mFilePathCallback.confirm(this, new Uri[]{data.getData()});
                    }             
snorp commented 4 years ago

onFilePrompt() doesn't return void, it returns GeckoResult<GeckoSession.PromptDelegate.PromptResponse>. The PromptResponse is the return value of GeckoSession.PromptDelegate.FilePrompt#confirm(). You need to create the GeckoResult and return that from onFilePrompt(), then later complete the result from your activity result callback. The example does this around here: https://searchfox.org/mozilla-central/source/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/BasicGeckoViewPrompt.java#761

skoolknot commented 4 years ago

It seems that PromptResponse (and FilePrompt) is missing

3 2

and the onFilePrompt() does return void.

Untitled

Probably I am using different GeckoView release. I have followed installation exactly as in documentation.

agi90 commented 4 years ago

What version of GeckoView are you on?

skoolknot commented 4 years ago

Did the installation based on documentation, it is version 70.0.20190712095934 (nightly release).

ext {
    geckoviewChannel = "nightly"
    geckoviewVersion = "70.0.20190712095934"
}

EDITED: I have updated the GeckoView version to the latest nightly release. Now I can use PromptResponse (and FilePrompt) and implement onFilePrompt(geckoSession:GeckoSession, filePrompt:FilePrompt):GeckoResult<PromptResponse>.

However, I still have problem with passing the URI back.

Here is the code in onFilePrompt.

 @Nullable
    @Override
    public GeckoResult<PromptResponse> onFilePrompt(@NonNull GeckoSession geckoSession, @NonNull FilePrompt filePrompt) {
        // Merge all given MIME types into one, using wildcard if needed (copied from BasicGeckoViewPrompt.java)
        ...

        // Set intent (copied from BasicGeckoViewPrompt.java)
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        ...

        GeckoResult<PromptResponse> res = new GeckoResult<>();
        mFileResponse = res; // Passing res to mFileResponse

        mFilePrompt = filePrompt; // Passing filePrompt to mFilePrompt

        startActivityForResult(intent, INPUT_FILE_REQUEST_CODE);

        return res;
    }

Here is the code in onActivityResult.

case INPUT_FILE_REQUEST_CODE:
                if (resultCode == RESULT_OK) {
                    if (mFileResponse == null || mFilePrompt == null) {
                        return;
                    } else {
                        if (data != null && data.getData() != null) {
                            Log.d(TAG, "onActivityResult: " + requestCode + " " + resultCode + " " + data);
                            Log.d(TAG, "onActivityResult: " + data.getData());
                            mFileResponse.complete(mFilePrompt.confirm(MainActivity.this, data.getData()));
                        }

                        mFileResponse = null;
                        mFilePrompt = null;
                    }
                }
                break;
a251115100 commented 3 years ago

您将必须提供以下实现PromptDelegate.FilePrompthttps : //mozilla.github.io/geckoview/javadoc/mozilla-central/org/mozilla/geckoview/GeckoSession.PromptDelegate.FilePrompt.html

GeckoView示例应用程序在此处具有实现:https ://searchfox.org/mozilla-central/source/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/BasicGeckoViewPrompt.java#712-769

我们的feature-prompts Android组件为所有提示提供了实现:https : //github.com/mozilla-mobile/android-components/tree/master/components/feature/prompts

You will have to provide an implementation of PromptDelegate.FilePrompt: https://mozilla.github.io/geckoview/javadoc/mozilla-central/org/mozilla/geckoview/GeckoSession.PromptDelegate.FilePrompt.html

The GeckoView example app has an implementation of it here: https://searchfox.org/mozilla-central/source/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/BasicGeckoViewPrompt.java#712-769

Our feature-prompts Android Component provides an implementation for all prompts: https://github.com/mozilla-mobile/android-components/tree/master/components/feature/prompts If there's a demo for a feature-prompt, I look at the library but I don't know how to use it. I can't even create a PromptFeature object.. Readme.md doesn't seem to be up to date

EgorSigolaev commented 1 month ago

After trying to execute the line fileResponse.complete(filePrompt.confirm(this, data)) there is error appearing in Logcat

Error resolving files from file picker: [Exception... "File error: Unrecognized path" nsresult: "0x80520001 (NS_ERROR_FILE_UNRECOGNIZED_PATH)" location: "JS frame :: resource://gre/modules/FilePickerDelegate.sys.mjs :: _getDOMFile :: line 117" data: no] Stack trace: _getDOMFile()@resource://gre/modules/FilePickerDelegate.sys.mjs:117 _resolveFiles()@resource://gre/modules/FilePickerDelegate.sys.mjs:67 open/<()@resource://gre/modules/FilePickerDelegate.sys.mjs:57 asyncShowPrompt()@resource://gre/modules/GeckoViewPrompter.sys.mjs:190

Uri which is passed is correct. How to fix this?