android使用webview上传文件(适配4.4以上系统)

在版本迭代中需要上传图片做统计,把链接发QQ上,里面的网页可以正常上传图片,但是我们自己app里不能上传。查了一些相关资料

默认情况下,Android的webview是不支持<input type=file>的,点击没有任何反应,如果希望点击上传,弹出选择文件、图片的窗口,我们可以重写webview的webchromeClient中的openFileChooser方法,由于android系统有多个版本,因此需要重写多个openFileChooser进行兼容,而android5.0以后,需要重写onShowFileChooser方法,其上传的参数Uri变成了Uri[]类型,说明5.0以后支持多传图片。查了很多文章,要么实现不了,要么对一些手机系统版本5.0及以上系统不适配或者手机型号不适配,总结前人经验及遇到的坑查找stackoverflow 外国大佬提供的经验,把实现方法分享一下,帮助小伙伴较少弯路。

可以用下面这个链接进行测试:

https://www.wenjuan.com/s/j67NJrg/

public class MyChromeClient extends WebChromeClient {
    public static ValueCallback<Uri> uriValueCallback;
    public static ValueCallback<Uri[]> valueCallbacks;
    private Activity activity;

    public static final int FILECHOOSER_RESULTCODE = 5173;

    public static String mCameraFilePath = "";

    @SuppressWarnings("deprecation")
    public MyChromeClient(Activity cordova) {
        this.activity = cordova;
    }

    @Override
    public void onProgressChanged(WebView view, int newProgress) {

        super.onProgressChanged(view, newProgress);

    }

    @Override
    public boolean onShowFileChooser(WebView webView,
                                     ValueCallback<Uri[]> filePathCallback,
                                     FileChooserParams fileChooserParams) {
        // TODO 自动生成的方法存根
        valueCallbacks = filePathCallback;
        this.activity.startActivityForResult(createDefaultOpenableIntent(),
                this.FILECHOOSER_RESULTCODE);
        return true;
    }


    public void openFileChooser(ValueCallback<Uri> uploadMsg,
                                String acceptType, String capture) {
        uriValueCallback = uploadMsg;
        this.activity.startActivityForResult(createDefaultOpenableIntent(),
                this.FILECHOOSER_RESULTCODE);

    }

    // 3.0 +

    @SuppressWarnings("static-access")
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {

        uriValueCallback = uploadMsg;

        this.activity.startActivityForResult(createDefaultOpenableIntent(),

                this.FILECHOOSER_RESULTCODE);

    }


    // Android < 3.0

    @SuppressWarnings("static-access")
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        uriValueCallback = uploadMsg;
        this.activity.startActivityForResult(createDefaultOpenableIntent(),
                this.FILECHOOSER_RESULTCODE);
    }


    private Intent createDefaultOpenableIntent() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                "image/*");
//        Intent chooser = createChooserIntent(createCameraIntent());
//        chooser.putExtra(Intent.EXTRA_INTENT, i);
        return i;

    }

    private Intent createChooserIntent(Intent... intents) {
        Intent chooser = new Intent(Intent.ACTION_CHOOSER);
        chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents);
        chooser.putExtra(Intent.EXTRA_TITLE, "选择图片");
        return chooser;
    }

    @SuppressWarnings("static-access")
    private Intent createCameraIntent() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File externalDataDir = Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
        File cameraDataDir = new File(externalDataDir.getAbsolutePath()
                + File.separator + "515aaa");
        cameraDataDir.mkdirs();
        String mCameraFilePath = cameraDataDir.getAbsolutePath()
                + File.separator + System.currentTimeMillis() + ".jpg";
        this.mCameraFilePath = mCameraFilePath;
        cameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(new File(mCameraFilePath)));
        return cameraIntent;
    }


    public static void update(Uri[] uris) {

        if ( valueCallbacks != null
                && uris[0] != null) {
            valueCallbacks.onReceiveValue(uris);
            valueCallbacks = null;
        }

        if(uriValueCallback != null
                && uris[0] != null){
            uriValueCallback.onReceiveValue(uris[0]);
            uriValueCallback = null;
        }

    }

}



在 对应的Activity中事件处理:

  /**
     * 返回文件选择
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode,
                                    Intent intent) {
        if (requestCode == MyChromeClient.FILECHOOSER_RESULTCODE&&
                intent!=null&&resultCode == RESULT_OK) {
            Uri[] uris = new Uri[1];
            uris[0] = intent.getData();
            MyChromeClient.update(uris);
        }
    }


测试手机有限,不知道还存在部分机型适配问题不,华为,小米,三星,以及4.x,5.x,6.x系统测试暂时没问题。


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值