问题:
在原生Android上嵌套H5,上传图片时,点击H5的上传控件,第一次能够调用,第二次点击无效。没有任何反应
发生场景:
之前做了一个项目,需要在原生Android上面嵌套一个H5页面,H5页面中有一个选择手机本地图片的功能。这就涉及到原生和H5的交互。但是才使用的过程中发现一个问题,第一次点击页面中的上传控件时能够调用原生的手机相册选择图片,再次点击控件上传时无效。
解决过程:
首页要知道H5与原生Android 的上传方式,我贴下核心代码
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadCallbackAboveL = filePathCallback;
ImageSelector.selectPic1((Activity)context,1);
//choseSinglePic(); // take();
return true;
}
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
//choseSinglePic();
}
//3.0--版本
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
// choseSinglePic();
}
// For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
mUploadMessage = uploadMsg;
// choseSinglePic();
}
});
上面的代码基本就满足了WebView 上传图片的需求,针对不同系统版本有不同的回调方法,onShowFileChooser()针对的是5.0及以上的系统。当我们通过 WebView 加载网页时,点击上传头像的按钮就回调这个方法。mUploadCallbackAboveL 就是将选择的图片回传给页面。在回调这个方法的时候,我们调用选择图片的代码。选择好图片返回后,调用 mUploadCallbackAboveL.onReceiveValue(Uri),这样就能完成整个选择图片并上传的过程。
所以我们需要重写一下 onActivityResult()方法:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri[] results = null;
if(resultCode ==Activity.RESULT_CANCELED && requestCode == ImageSelector.REQUEST_CODE_SELECT){
if( WebViewMangger.mUploadCallbackAboveL!=null ){
WebViewMangger.mUploadCallbackAboveL.onReceiveValue(null);
}
}else if (resultCode == Activity.RESULT_OK && requestCode == ImageSelector.REQUEST_CODE_SELECT) {
if (Build.VERSION.SDK_INT >= 21) {
if (WebViewMangger.mUploadCallbackAboveL == null) {
ToastUtils.show(this, "选择图片错误");
return;
}else {
List<Uri> mSelected = Matisse.obtainResult(data);
if (mSelected != null && mSelected.size() > 0) {
results = new Uri[mSelected.size()];
for (int i = 0; i < mSelected.size(); i++) {
results[i] = mSelected.get(i);
}
}
if(results==null||results.length==0){
WebViewMangger.mUploadCallbackAboveL.onReceiveValue(null);
}else{
WebViewMangger.mUploadCallbackAboveL.onReceiveValue(results);
}
WebViewMangger.mUploadCallbackAboveL = null;
}
} else {
if (WebViewMangger.mUploadCallbackAboveL == null) {
ToastUtils.show(this, "选择图片错误");
return;
} else {
List<Uri> mSelected = Matisse.obtainResult(data);
WebViewMangger.mUploadMessage.onReceiveValue(mSelected.get(0));
WebViewMangger.mUploadMessage = null;
}
}
}
}
在上面的代码中,我将WebView封装了一遍叫 WebViewMangger,到这里整个上传图片的功能就算是做完了,代码中,同样也分为两类 Build.VERSION.SDK_INT >= 21 以及 Build.VERSION.SDK_INT < 21
那么文章开始说的那个问题在那里发生的呢?
事实上,那个问题的场景是,在进入图片选择器之后,没有选择图片,直接返回了,这样会导致 mUploadCallbackAboveL 一直处于挂起状态,相当于一直处于等待反馈期间,这个时候你点击网页的上传图片按钮控件是无法被触发的。所以需要加上以下操作:
if(resultCode ==Activity.RESULT_CANCELED && requestCode == ImageSelector.REQUEST_CODE_SELECT){
if( WebViewMangger.mUploadCallbackAboveL!=null ){
WebViewMangger.mUploadCallbackAboveL.onReceiveValue(null);
}
}
当我们没有选择图片时,要手动回调 mUploadCallbackAboveL.onReceiveValue(null);这样就能避免第二次点击时无法调起图片选择器。
好了,以上就是该问题的解决过程,希望能帮到有需要的朋友!