android webview处理h5打开本地文件浏览器的功能

这周遇到一个比较棘手的问题,需要在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的权限!

  

时间: 2024-10-10 05:22:59

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

Android 打开本地文件

Android 打开本地的文件,目前来说,其实很常见.而且现在有手机版的office了.查看office的全家桶就更加方便. 首先要知道的是,Android 打开本地文件是根据类型打开的,也就是根据文件的 MIME 类型来确定 如果不知道是什么类型,那就是 : */* 类型匹配表: private static final String[][] MIME_MapTable={ //{后缀名, MIME类型} {".3gp", "video/3gpp"}, {&quo

H5读取本地文件操作

H5读取本地文件操作 本文转自:转:http://hushicai.com/2014/03/29/html5-du-qu-ben-di-wen-jian.html感谢大神分享. 常见的语言比如php.shell等,是如何读取文件的呢? 实际上,大多数语言都需要先获取文件句柄,然后调用文件访问接口,打开文件句柄,读取文件! 那么,HTML5是否也是这样的呢? 答案是肯定的! HTML5为我们提供了一种与本地文件系统交互的标准方式:File Api. 该规范主要定义了以下数据结构: File Fil

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

给IE浏览器地址栏输个本地文件路径,会自动用explorer.exe打开,这个挺好的,但是IE对jQuery稍微高点的版本不怎么待见,只好自己给Google折腾一个调用explorer的功能------ 1.自定义URL Protocol 协议,让浏览器可以启动本地程序 2.编写c++控制台程序:解码从浏览器传递过来的url(url===utf-8===Unicode===gb2312)-->将链接路径头部去掉-->替换"|"为"\\"(解码的时候会把u

用默认的打开方式打开本地文件

ShellExecute( hWnd: HWND; {指定父窗口句柄} Operation: PChar; {指定动作, 譬如: open.print} FileName: PChar; {指定要打开的文件或程序} Parameters: PChar; {给要打开的程序指定参数; 如果打开的是文件这里应该是 nil}     Directory: PChar; {缺省目录} ShowCmd: Integer {打开选项}): #include <Windows.h> ShellExecuteA

Notepad++如何关闭最近打开的文件的历史记录功能

Notepad++是Windows 操作系统下的一套非常有特色的自由软件的纯文字编辑器(许可证:GPL),有完整的中文化接口及支持多国语言编写的 功能(UTF8 技术).它的功能比Windows中的Notepad(记事本)强大,除了可以用来制作一般的纯文本文件也十分适合当作编写电脑程序的编辑器. 我们在安装完notepad++软件后,默认情况下.每次找开文件.都会有最近打开的文件的历史记录 如果要关闭默认的记录最近打开的文件记录,可以在设置-->首选项-->备份处 把Remember curr

android 之 webView 显示h5 执行选择图片或者拍照功能

开发工具是 android studio SDK版本是 4.3实现过程基本是这样h5中调用手机选择文件图片的代码是: <input accept="image/*" capture="camera" id="imgFile" name="imgFile" type="file"> 然后给webView 设置WebChromeClient WebChromeClient 主要处理解析,渲染网页等浏

Android WebView环境下打开相机、文件管理进行上传

Webview下面坑奇多,直接在浏览器下面可以直接调出相机和文件管理,但是在webview下面就是不行,在网上查阅了很多文章,不得不说坑奇多,最多终于拼拼凑凑成功了, 安卓版本为4.4.2,调试通过. 安卓端关键源码: protected ValueCallback<Uri> mUploadMessage; protected int FILECHOOSER_RESULTCODE = 1; private String mCameraFilePath; @SuppressLint("

js实现打开本地文件或文件夹

原网址:http://blog.csdn.net/cofesun/article/details/7904887javascript有个特殊的对象ActiveXObject,通过它可以访问windows的本地文件系统和应用程序 <script> function openFileIIs(filename){ try{ var obj=new ActiveXObject("wscript.shell"); if(obj){ obj.Run("\""

android获取一个用于打开Word文件的intent

最近在做项目使用webview显示后,有写文档需要打开,找了一些资料,研究了一下,弄出来了! 下面贴一下主要代码: param为文档的主要路径 public static Intent getWordFileIntent(String param) { Intent intent = null; try { intent = new Intent("android.intent.action.VIEW"); intent.addCategory("android.intent