[Android] WebView中拍照或从相册上传图片
WebView 上传图片, 想必很多人都碰到过这样的场景. 而且 WebView 在4.4前后的区别非常大, 比如对URL跳转的格式, 对JS的注入声明等等, 4.4以后的WebView 已经是chromium内核, 有多强大就无需我赘述. 说这些, 其实也是为了说明也因为WebView的前后变化太大了, 所以在低版本和版本上, WebView上传文件的方式都略有不同, 而且在安卓4.4.4的一些设备上难以保证所有机型都成功.
实现过程:
在4.4之前, WebView的webkit中支持openFileChooser. 当WebView加载一个HTML页面, 点击按钮需要模拟form提交的方式去上传文件时, 就会回调
openFileChooser(...)
方法. 然后在这个方法里接收并处理参数ValueCallback <uri> uploadMsg. 里面的 uri 就是所从本地选择的文件路径.
然后通过Intent的startActivityForResult(…) 方法跳转到系统选择文件的界面进行文件选择, 最后在
onActivityResult(int requestCode, int resultCode, Intent data)
方法中获取 data中的字符串路径, 并转换成Uri格式, 并传给uploadMsg 即可, 类似:
String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data);if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) {Log.e(TAG, "sourcePath empty or not exists.");break;
}
Uri uri = Uri.fromFile(new File(sourcePath));
mUploadMsg.onReceiveValue(uri);
这样, 接下来的上传工作, WebView会自动完成. 当然, 这是顺利的流程, 如果 onActivityResult(…) 中返回的 resultcode 不等于 Activity.RESULT_OK , 也要做一点处理, 不然再去点击第二次上传文件时是没有反应的. 类似这样:
if (resultCode != Activity.RESULT_OK) {if (mUploadMsg != null) {mUploadMsg.onReceiveValue(null);}return;
}
传个 null 即可.
OK, 上面就是4.4 以前的实现过程, 上面提及的代码在下载的demo里会有, 为保证篇幅不会放在文章里. 那么5.0及以上的sdk变动时, webkit不再支持
openFileChooser(...)
而是提供了一个代替的方法:
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,FileChooserParams fileChooserParams) {return false;
}
这个方法的参数跟 openFileChooser(…) 方法很像, 其实作用都是类似的, 只是 从
ValueCallback <uri> uploadMsg
变成了
ValueCallback<Uri[]> filePathCallback, 还多了FileChooserParams类型参数. fileChooserParams 其实是一个属性封装的参数, 里面包含了acceptType, title等这样的文件属性, 名称等信息.
所以, onShowFileChooser(…) 的使用方法跟 openFileChooser(…) 是很类似的, 这里通过 onActivityResult(…) 看两者的使用区别:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode != Activity.RESULT_OK) {if (mUploadMsg != null) {mUploadMsg.onReceiveValue(null);}if (mUploadMsgForAndroid5 != null) { // for android 5.0+mUploadMsgForAndroid5.onReceiveValue(null);}return;}switch (requestCode) {case REQUEST_CODE_IMAGE_CAPTURE:case REQUEST_CODE_PICK_IMAGE: {try {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {if (mUploadMsg == null) {return;}String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data);if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) {Log.e(TAG, "sourcePath empty or not exists.");break;}Uri uri = Uri.fromFile(new File(sourcePath));mUploadMsg.onReceiveValue(uri);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {if (mUploadMsgForAndroid5 == null) { // for android 5.0+return;}String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data);if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) {Log.e(TAG, "sourcePath empty or not exists.");break;}Uri uri = Uri.fromFile(new File(sourcePath));mUploadMsgForAndroid5.onReceiveValue(new Uri[]{uri});}} catch (Exception e) {e.printStackTrace();}break;}}
}
主要是针对 5.0前后的系统做了一些区别处理, 其他无大异.
测试说明
这里要特别说明的是, 经过我测试9部安卓手机, 从4.2 到6.0.1, 有8部都是正常使用. 其中包含 一部Android 4.4.2系统的手机 和 两部Android 4.4.4的手机, 发现在魅蓝note(4.4.4)上面是无法使用的, 因为4.4 Kitkat中webview是一个有点奇葩的存在, 问题这里不赘述, 有兴趣可以自行了解.
提高兼容性的解决方案:
1. 使用加强版的WebView, cordova , 可以考虑编译这个项目获得jar包, 然后导入项目中使用它的WebView组件.
2. 也可以通过JS调用本地的方法自行实现上传.
以上两个方法的兼容性都相当不错, 可自行尝试.
可能导致失败的原因
如果选择文件到上传文件的过程中失败, 有可能是以下原因导致的:
1. 文件的路径包含中文. (9部设备中, vivo X6D不支持中文路径包含中文)
2. 手机系统是Android 6.0以上 (API >= 23), 且没有获得文件和摄像头权限.
如果你的项目中还兼容到4.0以下的版本, build.gradle 配置文件中的compileSdkVersion 和 targetSdkVersion 是16甚至更低, 那么恭喜你, 直接使用
openFileChooser(...)
这种处理方法即可.
这个是原作者的demo
demo下载
下面贴一个我运行成功的demo
运行时间
2019年6月12日 16:54:27
https://gitee.com/liuande/webviewuploadimage.git
参考文章:
https://blog.csdn.net/stzy00/article/details/52831105
测试设备列表
1. 中移动 CM601 (4.2.2)
2. 华为荣耀6 H60-L01 (4.4.2)
3. 华为荣耀畅玩4X Che1-CL20 (4.4.4)
4. 魅蓝note (4.4.4)
5. 联想K50-t5 (5.0)
6. 魅蓝note3 (5.1)
7. vivo X6D (5.1)
8. 小米note (6.0.1)
9. 华为mate8 (6.0.1)
10. 三星Galaxy S6 SM-G9200 (6.0.1)
[Android] WebView中拍照或从相册上传图片相关推荐
- WebView中拍照或从相册上传图片
转载自WebView中拍照或从相册上传图片 注,安卓4.4系统的浏览器内核会出问题,即使使用本篇文章所讲的方法也无法吊起这个方法,属于谷歌系统的问题Stack Overflow 问题,但是4.4以上的 ...
- Android 使用腾讯X5 Webview浏览器拍照或从相册上传图片
最近在项目开发中,需要使用WebView上传文件.默认情况下情况下,使用Android的WebView是不能够支持上传文件的. 经过查找资料,得知需要重新WebChromeClient,根据选择到的文 ...
- android webview中h5调用 拍照/相册 通用支持代码
android webview中h5调用 拍照/相册 通用支持代码. 在webview的 WebChromeClient 中,重写 // For Android >= 5.0 @Overri ...
- Android实战场景 - 保存WebView中的图片到相册
去年同事写了一个 "在H5中保存图片到相册" 的功能,虽然有大致实现思路,实现起来也没问题,但是感觉同事考虑问题的很周全,当时候就想着去学习一下,但是项目太赶没顾得上,索性现在有时 ...
- android webview实现拍照
android webview实现拍照 1. html <div id="pnlVideo1"><input type="hidden" na ...
- android webview打印,javascript - 如何在Android Webview中使网站上的打印按钮工作? - 堆栈内存溢出...
我的网站上有一个模式按钮,在该按钮上附加了一个处理程序函数以打印模式. 该处理程序具有处理"仅打印模式"的代码,并最终运行window.print(). 该按钮的功能类似于浏览器中 ...
- android webview 支持ajax,Ajax在android webview中不起作用
我正在webview中加载一个网站,我们在网站上使用了Ajax,它在网页浏览器和移动浏览器上也运行良好,但在android webview中ajax无法正常工作,控制台中没有错误.这是我的代码: – ...
- 【Android开发技巧】 关于Webview拍照或从相册上传图片处理总结
新博客 前言: 各公司为了处理更多的业务流程, 一般都会加入H5与原生交互处理,方便快速开发,迭代项目.但,在Android中,H5与原生的交互处理的就没有iOS那么好.其中适配也是一个问题,Andr ...
- Android WebView中打开相机拍照和选择相册
一般在项目中与js交互,可能会遇到上传文件图片等操作,避免不了一些坑,下面简单说一下,Android 在不同版本中webView调用相机,选择相册的方法是不一样的,3.0以下的调用 public vo ...
最新文章
- 《C++游戏编程入门(第4版)》——1.8 Lost Fortune简介
- ADO.NET复习总结(4)--访问SqlServer的类
- mysql中like % %模糊查询
- Oracle 11.2.0.4.0 Dataguard部署和日常维护(7) - Dataguard Flashback篇
- 软件包的安装(源码安装)
- Android PopupWindow的简单说明
- 量子力学概论_科学网—《量子力学导论》潘必才 - 中国科大出版社的博文
- 钓鱼网站新花招 福彩赌球成噱头
- 黑客帝国里的酷炫蓝光屏幕
- MIMOl信道估计基本原理
- ASN.1入门(超详细)
- 我的推荐系统学习之路
- 神奇的三门问题,到底换不换门
- C语言指针基础与深入
- linux中的setenv命令
- TCP/IP 详解(第 2 版) 笔记 / 3 链路层 / 3.2 以太网与 IEEE 802 LAN/MAN 标准 / 3.2.2 以太网帧格式
- 神奇旋转,告诉我她是顺时针还是逆时针旋转
- 简单操作阿里云盘秒变电脑本地硬盘使用!秒多1T内存
- 浅析NI LabVIEW数据采集与处理信号的10大优势
- hive on spark 已测,完美搭建
热门文章
- uniapp城市列表_uni-app框架城市选择器
- oppo与vivo手机低版本兼容问题
- 解决vue中BMap未定义问题
- 计算机应用教研活动内容,2017年第一学期计算机组第八周教研活动记录
- 北上广工程师手机的必装App,为什么是“它”? | 自由职客
- 【机器学习】逻辑回归-基础认识与鸢尾花分类实操案例
- vivo是安卓手机吗_安卓手机运存越来越大 高运存能让手机变快,是真的吗
- 我的学生...我的事业...我的人生路...
- Linux系统没有groupadd命令怎么办
- Robotaxi和车联网会擦出什么爱情火花?