Android WebView选择文件

原创 2016年08月31日 15:50:27

      最近的项目需要和H5结合开发,其中一个功能就是要处理H5的选择文件功能,我也是第一次解决这种问题,首先就去百度看了很多博客写的处理方法,但是都没有很全面的解决方法,因为Android版本的不同,权限也相应的不一样,所以我就整理了针对不同的权限的解决方法。我主要是参考了http://download.csdn.net/detail/djcken/8776691这个博主的解决办法,并在他的基础上进行了修改。

  首先是要继承WebChromeClient这个类,WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等。

public class MyWebChomeClient extends WebChromeClient {

    private OpenFileChooserCallBack mOpenFileChooserCallBack;

    public ReWebChomeClient(OpenFileChooserCallBack openFileChooserCallBack) {
        mOpenFileChooserCallBack = openFileChooserCallBack;
    }

    //针对 Android 5.0+
    @Override
    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback,

                                     android.webkit.WebChromeClient.FileChooserParams fileChooserParams) {
        mOpenFileChooserCallBack.openFileChooser5CallBack(webView, valueCallback, fileChooserParams);
        return true;

    }


    //针对 Android版本 3.0+
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        mOpenFileChooserCallBack.openFileChooserCallBack(uploadMsg, acceptType);
    }

    // 针对 Android版本 < 3.0
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        openFileChooser(uploadMsg, "");
    }

    //针对 Android版本  > 4.1.1
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        openFileChooser(uploadMsg, acceptType);
    }

    //回调的接口
    public interface OpenFileChooserCallBack {
        void openFileChooserCallBack(ValueCallback<Uri> uploadMsg, String acceptType);

        void openFileChooser5CallBack(WebView webView, ValueCallback<Uri[]> valueCallback,
                                      android.webkit.WebChromeClient.FileChooserParams fileChooserParams);
    }

    @Override
    public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
        //  return super.onJsAlert(view, url, message, result);
        return true;
    }
}
接下来就是设置,一句代码就可以。
 webView.setWebChromeClient(new ReWebChomeClient(this));
 private static final int REQUEST_CODE_PICK_IMAGE = 0;
    private static final int REQUEST_CODE_IMAGE_CAPTURE = 1;
    private Intent mSourceIntent;
    //针对5.0以下版本
   private ValueCallback<Uri> mUploadMsg;
    //这对5.0以上版本
   private ValueCallback<Uri[]> mValueCallback;

    @Override
    public void openFileChooserCallBack(ValueCallback<Uri> uploadMsg, String acceptType) {
        mUploadMsg = uploadMsg;
        showOptions();
    }

    @Override
    public void openFileChooser5CallBack(WebView webView, ValueCallback<Uri[]> valueCallback, WebChromeClient.FileChooserParams fileChooserParams) {
        mValueCallback = valueCallback;
        showOptions();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_CANCELED) {
            if (mUploadMsg != null) {
                mUploadMsg.onReceiveValue(null);
                mUploadMsg = null;
            }
            if (mValueCallback != null) {
                mValueCallback.onReceiveValue(null);
                mValueCallback = null;
            }
        }
        switch (requestCode) {
            case REQUEST_CODE_IMAGE_CAPTURE:
            case REQUEST_CODE_PICK_IMAGE: {
                try {
                    if (mUploadMsg != null) {
                       String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data);
                        if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) {
                            Log.w(TAG, "sourcePath empty or not exists.");
                            break;
                        }
                        File file = new File(PictureUtil.bitmapToPath(sourcePath));
                        Uri uri = Uri.fromFile(file);
                        mUploadMsg.onReceiveValue(uri);
                        mUploadMsg = null;
                    } else if (mValueCallback != null) {
                        Uri[] uris = new Uri[1];

                        String sourcePath = ImageUtil.retrievePath(this, mSourceIntent, data);
                        if (TextUtils.isEmpty(sourcePath) || !new File(sourcePath).exists()) {
                            Log.w(TAG, "sourcePath empty or not exists.");
                            break;
                        }
                        File file = new File(PictureUtil.bitmapToPath(sourcePath));
                        uris[0] = Uri.fromFile(file);
                        if (uris[0] != null) {

                            mValueCallback.onReceiveValue(uris);

                        }
                        mValueCallback = null;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }

    public void showOptions() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
        alertDialog.setOnCancelListener(new ReOnCancelListener());
        alertDialog.setTitle(R.string.options);
        alertDialog.setItems(R.array.options, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (which == 0) {
                            mSourceIntent = ImageUtil.choosePicture();
                            startActivityForResult(mSourceIntent, REQUEST_CODE_PICK_IMAGE);
                        } else {
                            mSourceIntent = ImageUtil.takeBigPicture();
                            startActivityForResult(mSourceIntent, REQUEST_CODE_IMAGE_CAPTURE);
                        }
                    }
                }

        );
        alertDialog.show();
    }

    //这个必须要写,要不然第一次取消选择文件后第二次就调用不了选择文件这个功能了,所以一定要写
    private class ReOnCancelListener implements DialogInterface.OnCancelListener {

        @Override
        public void onCancel(DialogInterface dialogInterface) {
            if (mUploadMsg != null) {
                mUploadMsg.onReceiveValue(null);
                mUploadMsg = null;
            }
            if (mValueCallback != null) {
                mValueCallback.onReceiveValue(null);
                mValueCallback = null;
            }
        }
    }





版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

android利用h5上传图片遇到的问题

由于项目需求,需要在一个h5页面上实现图片上传的功能。整个流程是当点击h5然后webview会监听到这个事件接着在android原生这部分获取选中图片并将图片路径传回给h5页面处理并上传。监听这个选择...

Android使用WebView从相册/拍照中添加图片

解决这个问题花了很长时间搜索了解,网上大部分使用openFileChooser但都没解决一个存在的问题。就是当弹出选择图片/相机框之后,取消选择,就再也不能点击选择按钮了。这篇文章是为了记录这一点,为...
  • DJCKEN
  • DJCKEN
  • 2015-06-05 17:50
  • 20229

Android开发心得——网页通过webview调用Android的图片或文件选择

本博文欢迎转载,转载请注明来自http://www.cnblogs.com/qinxianyuzou/ 前段时间因为客户需求,做一个客户端结合web微网站的应用。其中,这个应用设计到了要修改头像...

关于android webview中访问web页面带有upload上传控件的解决办法

1、重写WebChromeClient,完成代码如下: package com.cxwl.nst.supplyinfor.activity; import android.graphics.Bit...

html5调用手机摄像头,实现拍照上传功能

http://www.glve.net/html5-calls-cell-phone-cameras-to-achieve-photo-upload-feature.html 今天做手机网站...

一次Android WebView使用的苦逼体验之旅

有时候有这么样的需求,我们想在自己的原生android app中嵌入其它功能模块,而这些模块的实现往往早就有BS模式的了,所以简单期间,直接拿过来用吧。 多亏了webView控件,让我们的app可以充...

Webview打开本地图片文件选择解决方案

Webview打开本地图片选择器解决方案Webview打开本地图片选择器十分之麻烦,其在安卓系统3x 4x 5x上的行为都不同,处理也不同,所以之前差点崩溃。经过测试和完善,最终其在各个版本上都能完美...
  • zhtsuc
  • zhtsuc
  • 2015-10-15 16:20
  • 14344

Android 5.0WebView选择本地文件

package com.bz365.project.activity.h5; import android.annotation.SuppressLint; import android.conte...

Android通过WebView选择文件上传(支持直接调起相机等应用)

前言 最近项目中上的一个banner,里面有个需求,需要在网页中调用系统的拍照功能或者选择文件,获取图片在网页显示出来,并上传到客户的服务器。但是在banner上线后,发现我们的app支持的Webv...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)