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

Posted 那年盛夏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的权限!

 

  

以上是关于android webview处理h5打开本地文件浏览器的功能的主要内容,如果未能解决你的问题,请参考以下文章

android Cache——webview的缓存处理

客户端相关知识学习之Android H5交互Webview实现localStorage数据存储

为啥 WebView 无法打开某些本地 URL(Android)?

Android WebView 实现缓存网页数据

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

如何在 WebView Android Studio 中打开本地 pdf 文件