• 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的权限!

      

  • 相关阅读:
    Linux下端口被占用确认
    Debuggex – 超好用的正则表达式可视化调试工具
    URL最大长度
    无需重启 修改计算机名直接生效
    UDP穿越NAT原理(p2p)
    gdb中信号
    锁 (读写锁优先级 写饥饿) (锁竞争引发的高系统调用)
    Loopback接口用途---用作管理地址。
    C/C++调试:gdbserver的简单使用
    总结一下NDK crash排查步骤
  • 原文地址:https://www.cnblogs.com/cmai/p/8005752.html
Copyright © 2020-2023  润新知