Skip to content

Fix WebView file handling and improve WebChromeClient implementation #316

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import android.net.Uri;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebChromeClient.CustomViewCallback;
import android.webkit.WebChromeClient.FileChooserParams;
import android.webkit.WebViewClient;
import android.webkit.WebSettings;
import android.annotation.SuppressLint;
Expand Down Expand Up @@ -152,6 +154,7 @@ public void setWebViewClient(final WebViewClient client) {
@Override
public void setWebChromeClient(final WebChromeClient client) {
mCustomWebChromeClient = client;
super.setWebChromeClient(client);
}

@SuppressLint("SetJavaScriptEnabled")
Expand Down Expand Up @@ -740,19 +743,38 @@ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
openFileChooser(uploadMsg, acceptType, null);
}

// file upload callback (Android 4.1 (API level 16) -- Android 4.3 (API level 18)) (hidden method)
/**
* File upload callback handler for Android 4.1-4.3 (API levels 16-18)
* Enhanced to properly handle file type filtering based on acceptType parameter
*/
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileInput(uploadMsg, null, false);
// Pass acceptType as an array to support proper MIME type filtering
openFileInput(uploadMsg, null, false, acceptType != null ? new String[] { acceptType } : new String[] { "*/*" });
}

// file upload callback (Android 5.0 (API level 21) -- current) (public method)
/**
* File chooser implementation for Android 5.0+ (API level 21+)
* Enhanced to properly clear previous callbacks and support MIME type filtering
*/
@SuppressWarnings("all")
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
// Clear any existing callback to prevent memory leaks
if (mFileUploadCallbackSecond != null) {
mFileUploadCallbackSecond.onReceiveValue(null);
}
// Store the new callback
mFileUploadCallbackSecond = filePathCallback;

// Delegate to custom implementation if available
if (mCustomWebChromeClient != null) {
return mCustomWebChromeClient.onShowFileChooser(webView, filePathCallback, fileChooserParams);
}

if (Build.VERSION.SDK_INT >= 21) {
final boolean allowMultiple = fileChooserParams.getMode() == FileChooserParams.MODE_OPEN_MULTIPLE;

openFileInput(null, filePathCallback, allowMultiple);
// Use accept types from parameters for proper MIME type filtering
openFileInput(null, filePathCallback, allowMultiple, fileChooserParams.getAcceptTypes());

return true;
}
Expand Down Expand Up @@ -1224,6 +1246,19 @@ protected static String decodeBase64(final String base64) throws IllegalArgument

@SuppressLint("NewApi")
protected void openFileInput(final ValueCallback<Uri> fileUploadCallbackFirst, final ValueCallback<Uri[]> fileUploadCallbackSecond, final boolean allowMultiple) {
openFileInput(fileUploadCallbackFirst, fileUploadCallbackSecond, allowMultiple, null);
}

/**
* Opens a file input dialog that supports MIME type filtering
*
* @param fileUploadCallbackFirst Callback for older Android versions (pre-Lollipop)
* @param fileUploadCallbackSecond Callback for Android Lollipop and above
* @param allowMultiple Whether to allow selection of multiple files
* @param acceptTypes Array of acceptable MIME types for filtering
*/
@SuppressLint("NewApi")
protected void openFileInput(final ValueCallback<Uri> fileUploadCallbackFirst, final ValueCallback<Uri[]> fileUploadCallbackSecond, final boolean allowMultiple, final String[] acceptTypes) {
if (mFileUploadCallbackFirst != null) {
mFileUploadCallbackFirst.onReceiveValue(null);
}
Expand All @@ -1243,6 +1278,11 @@ protected void openFileInput(final ValueCallback<Uri> fileUploadCallbackFirst, f
}
}

if (acceptTypes != null) {
i.putExtra(Intent.EXTRA_MIME_TYPES, acceptTypes);
}

// set MIME type to filter filetype, default is "*/*"
i.setType(mUploadableFileTypes);

if (mFragment != null && mFragment.get() != null && Build.VERSION.SDK_INT >= 11) {
Expand Down