Android与WebView本地上传图片问题
问题:
在原生Android上嵌套H5,上传图片时,点击H5的上传控件,第一次能够调用,第二次点击无效。没有任何反应
发生场景:
之前做了一个项目,需要在原生Android上面嵌套一个H5页面,H5页面中有一个选择手机本地图片的功能。这就涉及到原生和H5的交互。但是才使用的过程中发现一个问题,第一次点击页面中的上传控件时能够调用原生的手机相册选择图片,再次点击控件上传时无效。
解决过程:
首页要知道H5与原生Android 的上传方式,我贴下核心代码
webView.setWebChromeClient(new WebChromeClient() { @Override public boolean onShowFileChooser(WebView webView, ValueCallback 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 uploadMsg) { mUploadMessage = uploadMsg; //choseSinglePic(); } //3.0--版本 public void openFileChooser(ValueCallback uploadMsg, String acceptType) { mUploadMessage = uploadMsg; // choseSinglePic(); } // For Android 4.1 public void openFileChooser(ValueCallback 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 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 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);这样就能避免第二次点击时无法调起图片选择器。
好了,以上就是该问题的解决过程,希望能帮到有需要的朋友!
更多相关文章
- Android 中,应用程序需要的图片资源如何针对不同屏幕大小手机设计
- 一款用于在 Android 设备上获取照片(拍照或从相册、文件中选择)、
- Android注解式绑定控件,没你想象的那么难
- Android Tween动画之RotateAnimation实现图片不停旋转效果实例介
- Android中一张图片占用的内存大小
- [置顶] android中图片的三级cache策略(内存、文件、网络)之三:文件
- Android拖动和缩放图片