現象:iOS 正常喚起相機/相冊,Android WebView 點擊 <input type="file"> 無反應,不觸發 change 事件。根因:Android WebView **默認不處理文件選擇**,必須設置 WebChromeClient 並實現 onShowFileChooser / openFileChooser 系列回調。
webView.setWebChromeClient(new WebChromeClient() {
// Android 5.0+ (API 21)
@Override
public boolean onShowFileChooser(WebView webView,
ValueCallback filePathCallback,
FileChooserParams fileChooserParams) {
mUploadCallbackAboveL = filePathCallback;
openFileChooserIntent();
return true;
}
// Android 3.0 - 4.4
public void openFileChooser(ValueCallback uploadMsg) {
mUploadMessage = uploadMsg; openFileChooserIntent();
}
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
mUploadMessage = uploadMsg; openFileChooserIntent();
}
public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) {
mUploadMessage = uploadMsg; openFileChooserIntent();
}
});
private void openFileChooserIntent() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
Intent chooser = Intent.createChooser(i, "選擇圖片");
startActivityForResult(chooser, FILECHOOSER_RESULTCODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == FILECHOOSER_RESULTCODE) {
if (mUploadCallbackAboveL != null) { // API 21+
Uri[] results = data == null ? null : new Uri[]{data.getData()};
mUploadCallbackAboveL.onReceiveValue(results);
mUploadCallbackAboveL = null;
} else if (mUploadMessage != null) { // 旧版
mUploadMessage.onReceiveValue(data == null ? null : data.getData());
mUploadMessage = null;
}
}
}
Activity 中處理 onActivityResult 回傳 Uri 給回調VALUE_CALLBACK 變量需為成員變量,防止被 GCREAD_EXTERNAL_STORAGE 動態申請