这周遇到一个比较棘手的问题,需要在android上边集成h5页面,并且在h5页面上,需要用户能够上传android本地的照片,一开始我以为webview会自动处理掉的,因此没太留意,当真正集成时,才发现,h5界面上传图片无法打开本地android的图库,h5调用的方式是:

<input type = "file"/>

通过最为简单的input菜单来选择,于是我就百度了一波,找到了两种比较好的解决方法,一种是h5编写js代码,调用android app实现的函数,来实现打开图库进行图片选择的功能,还有一种方法是,通过重写webview中WebChromeClient类,然后来进行实现打开本地图库的功能。

在这主要讲述第二种方法的实现。

我这先放上重写的代码:

public class OpenFileWebChromeClient extends WebChromeClient {
public String TAG = "OpenFileWebChromeClient";
public static final int REQUEST_FILE_PICKER = 1;
public ValueCallback<Uri> mFilePathCallback;
public ValueCallback<Uri[]> mFilePathCallbacks;
private Activity mContext;
private TextView textView; public OpenFileWebChromeClient(Activity mContext) {
super();
this.mContext = mContext;
} /**
* Android < 3.0 调用这个方法
*/
public void openFileChooser(ValueCallback<Uri> filePathCallback) {
mFilePathCallback = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
mContext.startActivityForResult(Intent.createChooser(intent, "File Chooser"),
REQUEST_FILE_PICKER);
} /**
* 3.0 + 调用这个方法
*/
public void openFileChooser(ValueCallback filePathCallback,
String acceptType) {
mFilePathCallback = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
mContext.startActivityForResult(Intent.createChooser(intent, "File Chooser"),
REQUEST_FILE_PICKER);
} /**
* js上传文件的<input type="file" name="fileField" id="fileField" />事件捕获
*/ /**
* Android > 4.1.1 调用这个方法
*/
@Deprecated
public void openFileChooser(ValueCallback<Uri> filePathCallback,
String acceptType, String capture) {
mFilePathCallback = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
mContext.startActivityForResult(Intent.createChooser(intent, "File Chooser"),
REQUEST_FILE_PICKER);
} @Override
public boolean onShowFileChooser(WebView webView,
ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
mFilePathCallbacks = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
mContext.startActivityForResult(Intent.createChooser(intent, "File Chooser"),
REQUEST_FILE_PICKER);
return true;
} }

这样既可打开本地的图库,当然,这只是能够打开了,选择后的图片又怎样返回给h5页面呢?

需要在activity中实现如下的代码:

    @Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == OpenFileWebChromeClient.REQUEST_FILE_PICKER) {
if (mOpenFileWebChromeClient.mFilePathCallback != null) {
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
: intent.getData();
if (result != null) {
String path = MediaUtility.getPath(getApplicationContext(),
result);
Uri uri = Uri.fromFile(new File(path));
mOpenFileWebChromeClient.mFilePathCallback
.onReceiveValue(uri);
} else {
mOpenFileWebChromeClient.mFilePathCallback
.onReceiveValue(null);
}
}
if (mOpenFileWebChromeClient.mFilePathCallbacks != null) {
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
: intent.getData();
if (result != null) {
String path = MediaUtility.getPath(getApplicationContext(),
result);
Uri uri = Uri.fromFile(new File(path));
mOpenFileWebChromeClient.mFilePathCallbacks
.onReceiveValue(new Uri[] { uri });
} else {
mOpenFileWebChromeClient.mFilePathCallbacks
.onReceiveValue(null);
}
} mOpenFileWebChromeClient.mFilePathCallback = null;
mOpenFileWebChromeClient.mFilePathCallbacks = null;
}
}

这样,返回的数据则是h5页面需要的数据,这样一来,h5就可以像在电脑上一样的,对返回的数据进行操作,可以进行实时的预览,上传等功能。

但是对于以上的方法,我们在测试的时候发现,在android4.4上是不支持的,原因则是android4.4的webview没有对onShowFileChooser和openFileChooser做任何的处理,因此不支持,这算是android上的一个坑吧。

最后,记得添加权限,因为要读取本地的图片,所以要获取读本地sdcard的权限!

  

android webview处理h5打开本地文件浏览器的功能的更多相关文章

  1. 【Electron】Electron开发入门(七):打开本地文件或者网页链接 and webview里操纵electron api

    1.打开本地文件或者网页链接 // 打开系统本地文件 const {shell} = require('electron'); // Open a local file in the default ...

  2. Android WebView与H5联调技巧

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/78 背景: 突然想写一篇关于Android WebView ...

  3. H5读取本地文件操作

    H5读取本地文件操作 本文转自:转:http://hushicai.com/2014/03/29/html5-du-qu-ben-di-wen-jian.html感谢大神分享. 常见的语言比如php. ...

  4. web打开本地文件并读取内容

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. 设置Adobe Reader打开PDF文件保持记忆功能

    设置Adobe Reader打开PDF文件保持记忆功能 打开菜单“编辑”->“首选项”. 选择种类中的“文档”,在“打开设置”区域勾上“重新打开文档时恢复上次视图设置(R)”,确定之后就可以在下 ...

  6. Google调用explorer.exe打开本地文件

    给IE浏览器地址栏输个本地文件路径,会自动用explorer.exe打开,这个挺好的,但是IE对jQuery稍微高点的版本不怎么待见,只好自己给Google折腾一个调用explorer的功能----- ...

  7. android红米等关于读取本地文件夹图片获取路径的问题的解决

    在Android开发中,有从本地文件夹中读取图片的功能,使用一下代码打开图片选择列表: Intent intent = new Intent();   intent.setAction(Intent. ...

  8. [AIR] AIR程序调用本地默认应用程序打开本地文件

    摘要:      File类提供了一个方法openWithDefaultApplication可以用本地默认应用程序打开指定路径下的文件. 当我用下面语句的时候,可以成功打开桌面文件夹下面的文件: v ...

  9. Android使用文件管理器打开指定文件夹,浏览里面的内容

    Android下可以打开一些文件,带有.doc 等后缀的文件网上一般都有解释,这个写一个使用文件管理器打开指定文件夹的 private void openAssignFolder(String pat ...

随机推荐

  1. Android轻量级的开源缓存框架ASimpleCache

    点击查看原文 先上方法调用,写最经常使用的.其它不一一写 保存数据: ACache mACache=ACache.get(this); mACache.put("数据名称", js ...

  2. profile_oracle设置某用户password永只是期

    原创作品.出自 "深蓝的blog" 博客,深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/46888139 or ...

  3. hdu4515小Q系列故事——世界上最遥远的距离

    Problem Description 世界上最遥远的距离 不是生与死 而是我就站在你面前 你却不知道我爱你 世界上最遥远的距离 不是我就站在你面前你却不知道我爱你 而是明明知道彼此相爱 却不能在一起 ...

  4. 如何利用ps去批量完成一套任务

    作为前端开发人员,不说设计你会不会,ps作为一个工具来说,前端开发人员还是要熟悉才行的 做了一个项目,客户自己上传了图片,他表示上传非常慢,我们表示不解,为何那么慢,网络问题吗,经过看了她的图片,发现 ...

  5. 更新node版本

    步骤如下:1.查看当前的node版本 node -v 2.清除npm当前缓存信息 npm cache clean -f 3.执行下载node npm install -g n 4.下载成功后执行安装 ...

  6. iDempiere VS ADempiere

    怀揣着为中小企业量身定做一整套开源软件解决方案的梦想开始了一个网站的搭建.http://osssme.org/ 第三篇:iDempiere VS ADempiere 一直以来,什么谁谁谁VS谁谁谁的, ...

  7. 解决在IE9,IE10浏览器下,程序没有任何错误,easy ui页面不加载任何数据的问题

    对于web应用程序,经常用到开发人员工具,按F12,可以调试脚本,可以查看监视网络,查看各页面加载时间,非常方便,今天在调试js时,不小心打开了兼容性视图, 之后每次打打开页面时,均不显示页面post ...

  8. 产品经理PM

    首先希望大家记住的就是,千万不要以为产品经理是什么高大上的光环,产品经理其实只是一种状态,一种心态而已. 大家可能看到BAT每年都会从校园里面招聘一些产品经理,尤其是我们腾讯,声称以产品为王,每年投产 ...

  9. nodejs express route 的用法

    express 中文社区:http://expressjs.jser.us/community.html nodejs express route 的用法 1. 首先是最基本的用法. 1 2 3 4 ...

  10. 检查SSD磁盘是否开启了TRIM指令

    fsutil behavior QUERY DisableDeleteNotify 如果查询结果是“DisableDeleteNotify = 0”,代表SSD已经支持并启用Trim指令:如果提示为“ ...