android Webview 上传图片兼容各android版本

android 提供了支持网页的Webview控件,相当于一个小型的浏览器。当html网页中input type为“file”类型的form表单,并用户点击“选择文件”按钮时,Webview向客户端提供一个回调方法(安卓各版本不一致),用于让开发人员提供图片的Uri地址,并回传到网页。
整个过程比较明了,但是由于android的系统优化升级,高版本Webview,没有保留老版本图片上传的回调方法,而是重新构造了新的回调方法。系统不是deprecated,而是直接delete了(0_0),目的是为了更好的扩展性。好吧,那我们就来做兼容。
下面就开始实现上传图片:
1.添加权限。
不用多说了,必须用到的权限:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.CAMERA" />

2.实现自定义WebChromeClient类,并重写各版本需要的回调方法。

class MyWebChromeClient extends WebChromeClient {


        // For Android < 3.0
        public void openFileChooser(ValueCallback uploadMsg) {
            mUploadMessage = uploadMsg;
            showOptions();
        }

        // For Android > 4.1.1
        public void openFileChooser(ValueCallback uploadMsg,
                String acceptType, String capture) {
            mUploadMessage = uploadMsg;
            showOptions();
        }

        // For Android > 5.0支持多张上传
        @Override
        public boolean onShowFileChooser(WebView webView,
                ValueCallback uploadMsg,
                FileChooserParams fileChooserParams) {
            mUploadCallbackAboveL = uploadMsg;
            showOptions();
            return true;
        }


}
/**
 * 包含拍照和相册选择
 */
public void showOptions() {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
    alertDialog.setOnCancelListener(new ReOnCancelListener());
    alertDialog.setTitle("选择");
    alertDialog.setItems(R.array.options,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    if (which == 0) {
                        if (ContextCompat.checkSelfPermission(context,
                                Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                            // 申请WRITE_EXTERNAL_STORAGE权限
                            ActivityCompat
                                    .requestPermissions(
                                            (Activity) context,
                                            new String[] { Manifest.permission.CAMERA },
                                            TYPE_REQUEST_PERMISSION);
                        } else {
                            toCamera();

                        }
                    } else {
                        Intent i = new Intent(
                                Intent.ACTION_PICK,
                                MediaStore.Images.Media.EXTERNAL_CONTENT_URI);// 调用android的图库
                        ((Activity) context).startActivityForResult(i,
                                TYPE_GALLERY);
                    }
                }
            });
    alertDialog.show();
}

3.拍照和选择图库
选择图库比较简单,通过Intent向系统发送MediaStore.Images.Media.EXTERNAL_CONTENT_URI的图片选择请求,在Activity中会回调一个Uri,这个就是图片的地址格式类似这样:
uri=content://media/external/images/media/1393
拍照是先定义一个创建一个图片文件,然后通过Uri.fromFile(File)拿到文件的Uri地址
通过这两种方式拿到Uri之后,通过ValueCallback对象的onReceiveValue(Uri)方法,将图片地址上传成功。图片上传到服务器当然是html通过ajax请求做的,和我们没关系。

 /**
     *  回调到网页
     * @param isCamera
     * @param uri
     */
    public void onActivityCallBack(boolean isCamera, Uri uri) {
        if (isCamera) {
            uri = fileUri;
        }

        if (mUploadCallbackAboveL != null) {
            Uri[] uris = new Uri[]{uri};
            mUploadCallbackAboveL.onReceiveValue(uris);
            mUploadCallbackAboveL = null;
        } else if (mUploadMessage != null) {
            mUploadMessage.onReceiveValue(uri);
            mUploadMessage = null;
        } else {
            Toast.makeText(context, "无法获取数据", Toast.LENGTH_LONG).show();
        }
    }

ok,到此就完成网页上传图片了,下面附上源码。注:源码中的测试url是我从网上找的,如果内部功能失效了建议换个有上传图片的html。

下载地址

你可能感兴趣的:(android,开发)