有时候用webview加载了一个页面,页面里有上传文件或者图片的按钮,点击要唤起本地文件选择器,可以借鉴以下代码:
webview.setWebChromeClient(new FilePickWebChromeClient());//这个无需解释了 以下是FilePickWebChromeClient的具体代码
//两个处理文件选择后回调给web的变量
ValueCallback<Uri> mUploadMessage;
ValueCallback<Uri[]> mFilePathCallback;
//FilePickWebChromeClient
private class FilePickWebChromeClient extends WebChromeClient {
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
if (mFilePathCallback != null)
return true;
mFilePathCallback = filePathCallback;//一个回调的初始化
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//如果选择的是拍照,这个值应该是类似这种image/jpeg,image/jpg,image/gif,image/png,image/bmp,所以我选择了判断包含
if(fileChooserParams.getAcceptTypes()[0].contains("image")){
selectImage();//选择图片
}else{
selectFile();//选择文件
}
}
return true;
}
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
//此处同以上
if (mUploadMessage != null)
return;
mUploadMessage = uploadMsg;//另一个回调的初始化
if(!StringUtil.isEmpty(acceptType) && acceptType.contains("image")){
selectImage();
}else {
selectFile();
}
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser( uploadMsg, "" );
}
// For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}
}
//#################### 以上为FilePickWebChromeClient #########################
public static final int REC_REQUESTCODE = 1;
//选择文件 开始调用系统的文件选择器
private void selectFile() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");//这个是所有类型文件的筛选 如果只想要图片可以设置image/* 网上有各种文件类型的说明,可以根据自己的需要配置
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent,REC_REQUESTCODE);
}
//#################### 以上为调用系统文件选择器 #########################
//选择文件后的回调
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//判断事件完成,就是选择完图片
try {
if (requestCode == REC_REQUESTCODE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (data != null) {
uri = data.getData();
//拿到Uri web回调只需要uri 所以转成绝对地址什么的是没有意义的
if(mFilePathCallback != null){
Uri[] uris = new Uri[1];
uris[0] = uri;
mFilePathCallback.onReceiveValue(uris);//回调
}else {
mUploadMessage.onReceiveValue(uri);//或者另一种回调
}
mFilePathCallback = null;
mUploadMessage = null;
}
}
} catch (Exception ex) {
}finally {
//重点来了 !!!一次按钮点击 唤起事件后 无论你是否选择了文件 最后结束操作都必须调用以下内容 否则按钮就会出现只能点一次的现象,点击第二次就会无反应,
if(mFilePathCallback != null){
Uri[] uris = new Uri[1];
uris[0] = Uri.parse("");
mFilePathCallback.onReceiveValue(uris);
mFilePathCallback=null;
}else if(mUploadMessage != null){
mUploadMessage.onReceiveValue(Uri.parse(""));
mUploadMessage=null;
}
}
}
//#################### 以上为回调 #########################
此代码测试机型为
Nexus6P 原生Android7.1.2
MotoX2代 原生Android5.1
小米6 MIUI8.2.25.0 Android7.1.1