androidandroid-webviewwebchromeclient

Workaround for file uploads on Android 4.4 using reflection


From Android 4.1 to Android 4.3, you could subclass WebChromeClient on Android and implement the following (hidden, thus no @Override) method:

public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { ... }

You would open a file picker in that method, and when your Activity receives the result in onActivityResult(...), just call the single method that is available on the ValueCallback<Uri> instance with the file URI. That's it.

Unfortunately, this method was removed from the API in Android 4.4 and is not being called anymore.

Is there any way you can work around this, e.g. with reflection?

I mean, you could set an onclick="..." listener on the <input type="file"> element in HTML, which would still be called.

After intercepting the onclick="..." callback in Java (maybe via addJavascriptInterface(...)) you could open a file picker as usual. But the problem is that there's no ValueCallback<Uri> instance available that you could send your result (the file that was picked) to.

Setting the value="..." of the <input type="file"> in HTML manually is not possible, either, because it's read-only. But the WebView implementation itself can certainly write the value, obviously. So could you use reflection to set the value there or find another workaround?

I'm searching for a cleaner and more comfortable solution than detecting the <input type="file"> click (e.g. via its onclick="..." listener) and doing the file selection and file upload manually from Java. Enabling file uploads in the WebView, as they should work, would be cleaner, certainly.


Solution

  • If you're looking for a clean solution to do this this without using tricky Javascript codes and detectors. I'd recommend using a Webview alternative.

    Crosswalk
    I'd recommend this. It'll work similar to the official webview. It's open source and made by the same people behind ChromeView. They've got a great setup guide: https://crosswalk-project.org/documentation/embedding_crosswalk.html

    Check it out: https://crosswalk-project.org/

    Chromium Webview
    Also inspired by ChromeView. They claim to have integrated the same API's as the official webview for easy migration. But they indicate that the Webview still might be a bit unstable.

    Check it out: https://github.com/mogoweb/chromium_webview

    GeckoView
    Made by Mozilla. Here's a demo project that uses it. Mozilla warns: "This is not a drop webview replacement and very unstable", but it has file upload

    Check it out: https://wiki.mozilla.org/Mobile/GeckoView

    If you're open on using Javascript (perhaps usefull for others) try:

    Kitkat Webview
    It uses javascript to enable file upload in KitKat webview do this. The demo allows you to upload an image, but you should be able to edit it to fit your needs.

    Check it out: https://github.com/henrychuangtw/Kitkat-WebView