Android-WebView-解决对选择文件<input type="file">无响应
2017-08-31 18:46
801 查看
发现一个 WebView 的坑:
上个周,项目中有需要接入一个 H5 页面,H5 中有上传图片的功能,接入测试的时候,发现 iOS 端正常,但是所有的 Android 手机在点击上传图片的按钮时,都毫无反应 。当时我的表情是这样的 (˶‾᷄ ⁻̫ ‾᷅˵) 。问题原因:
原因是 H5 访问本地文件的时候,使用的
<input type="file">,WebView 出于安全性的考虑,限制了以上操作。
解决方法:
重写 WebviewChromeClient 中的 openFileChooser() 和 onShowFileChooser()方法响应
<input type="file">,然后使用原生代码来实现调用本地相册和拍照的功能,最后在 onActiivtyResult 把选择的图片 URI 回传给 WebviewChromeClient。
逻辑分析
首先明确下,我需要做的工作有:1.弹出对话框选择相机或相册
2.调用系统相册的实现代码
3.调用系统相机拍照的实现代码
4.需要兼容 6.0 的动态权限问题和 7.0 的文件管理问题。
5.相机拍照后的图片上传后要进行删除,以免占用手机存储空间
列下来觉得还是蛮多的。
博主实现完 Demo,并扔给你一段核心代码
WebviewChromeClient 中重写方法响应<input type="file">。
4.1以上系统,使用 openFileChooser() ,该方法5.0已经被废弃
5.0以上系统,使用 onShowFileChooser()
mWebView.setWebChromeClient(new WebChromeClient() { //For Android >= 5.0 @Override public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { uploadMessageAboveL = filePathCallback; //调用系统相机或者相册 uploadPicture(); return true; } //For Android >= 4.1 public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) uploadMessage = valueCallback; //调用系统相机或者相册 uploadPicture(); } });
调用相机和相册选择图片后,在 onActivityResult() 中将图片的 Uri 通过 uploadMessage,5.0以上用 uploadMessageAboveL,使用 onReceiveValue 回传过去。
这里需要注意的是,当取消拍照或者未选择照片的时候,uploadMessage 或者 uploadMessageAboveL 要返回 null.因为 valueCallback 持有的是 WebView,在 onReceiveValue 没有回传值的情况下,WebView 无法进行下一步操作,会导致取消选择文件后,点击
<input type = 'file'>,不会再响应。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_ALBUM || requestCode == REQUEST_CODE_CAMERA) { if (uploadMessage == null && uploadMessageAboveL == null) { return; } //取消拍照或者图片选择时,返回null,否则<input file> 就是没有反应 if (resultCode != RESULT_OK) { if (uploadMessage != null) { uploadMessage.onReceiveValue(null); uploadMessage = null; } if (uploadMessageAboveL != null) { uploadMessageAboveL.onReceiveValue(null); uploadMessageAboveL = null; } } //拍照成功和选取照片时 if (resultCode == RESULT_OK) { Uri imageUri = null; switch (requestCode) { case REQUEST_CODE_ALBUM: if (data != null) { imageUri = data.getData(); } break; case REQUEST_CODE_CAMERA: if (!TextUtils.isEmpty(mCurrentPhotoPath)) { File file = new File(mCurrentPhotoPath); Uri localUri = Uri.fromFile(file); Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri); sendBroadcast(localIntent); imageUri = Uri.fromFile(file); mLastPhothPath = mCurrentPhotoPath; } break; } //上传文件 if (uploadMessage != null) { uploadMessage.onReceiveValue(imageUri); uploadMessage = null; } if (uploadMessageAboveL != null) { uploadMessageAboveL.onReceiveValue(new Uri[]{imageUri}); uploadMessageAboveL = null; } } } }
最后不要忘记,在项目的混淆文件中加入以下规则,保护 openFileChooser() 不被混淆,否则混淆后的包在 Android 4.X 不能正常使用。
#确保openFileChooser方法不被混淆 -keepclassmembers class * extends android.webkit.WebChromeClient{ public void openFileChooser(...); }
调用系统相机和相册的代码,因为动态权限申请和文件删除的功能,搞的太长了,就不贴了。下面是完整代码的 github 项目地址:
https://github.com/DRPrincess/DR_WebviewDemo
参考资料
Android爬坑之旅之WebViewAndroid WebView那些坑之上传文件
最后
刚刚开通了个人微信公众号,最新的博客,好玩的事情,都会在上面分享,欢迎关注 (^o^)。相关文章推荐
- [Cordova] 改进InAppBrowser插件(WebView),让其<input type="file">支持选择文件
- [Cordova/Phonegap] 改进InAppBrowser插件(WebView),让其<input type="file">支持选择文件
- Android:让WebView支持<input type="file"…>元素,实现文件上传
- WebView支持<input type="file">调起本地文件,获取图片
- Android WebView 支持H5图片上传<input type="file">
- HTML+CSS优化“文件选择”控件(<input type="file">)
- Android:让WebView支持<input type=”file”…>元素
- 判断多个<input type="file">是否有已经选择好文件的
- Android WebView 不支持 H5 input type="file" 解决方法
- android webview支持<input type="file"类型
- 关于JSP中单击任意标签弹出文件选择框(<input type="file"/>)的实现方法
- WebView 加载H5 <Input type="file"/>标签上传图片问题
- Android webview Input type=file 文件上传 解决方法
- Android学习之实现WebView中input="file"选择文件,处理选择图片无法返回类型问题
- The solution of html <input type = "file "> in webview not work
- Android WebView 不支持 H5 input type="file" 解决方法
- Android:让WebView支持<input type=”file”…>元素
- Android WebView 不支持 H5 input type="file" 解决方法
- 解决微信内嵌浏览器无法响应<input type='file'>上传文件的思路
- android webview使用html5<input id="input" type="file"/> 上传相册、拍照照片