Android webview支持type="file" 打开相机和相册,支持小米(亲测6.0通过)

转载自:https://zhuanlan.zhihu.com/p/21386201
注意:在小米Max上面无效
此处也是不支持小米啊:http://www.miui.com/thread-1936287-1-1.html
作者:杨同学
链接:https://zhuanlan.zhihu.com/p/21386201
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

private final static int FILECHOOSER_RESULTCODE = 1;
private String mCameraFilePath = null;
private ValueCallback<Uri> mUploadMessage;
private Uri imageUri;

webView.setWebChromeClient(new WebChromeClient() {
            // For Android 3.0+
            public void openFileChooser(ValueCallback<Uri> uploadMsg) {
                mUploadMessage = uploadMsg;

                File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "TestApp");
                if (!imageStorageDir.exists()) {
                    imageStorageDir.mkdirs();
                }
                File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
                imageUri = Uri.fromFile(file); // save to the private variable

                final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                i.addCategory(Intent.CATEGORY_OPENABLE);
                i.setType("image/*");

                Intent Photo = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

                Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
                chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[] { captureIntent, Photo });

               startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
            }

            // For Android 3.0+
            public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
                openFileChooser(uploadMsg);
            }

            // For Android 4.1
            public void openFileChooser(ValueCallback<Uri> uploadMsg,
                                        String acceptType, String capture) {
                openFileChooser(uploadMsg);
            }
        });
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == FILECHOOSER_RESULTCODE) {
            if (null == this.mUploadMessage) {
                return;
            }
            Uri result;
            if (resultCode != Activity.RESULT_OK) {
                result = null;
            } else {
                result = intent == null ? this.imageUri : intent.getData(); // retrieve from the private variable if the intent is null
            }

            this.mUploadMessage.onReceiveValue(result);
            this.mUploadMessage = null;
        }
    }

测试在Max中测试无效,后来找到解决方法
这里:http://blog.saymagic.cn/2015/11/08/webview-upload.html(测试支持小米Max,别的版本没有机器没有测)
—————–2016年9月1日09:25:03————————
修改之后的代码:

package com.shangyi.ui.activity;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.view.View;
import android.view.WindowManager;
import android.widget.ProgressBar;

import com.shangyi.app.Contants;
import com.shangyi.base.BaseActivity;
import com.shangyi.log.SyLog;
import com.shangyi.supplier.R;
import com.shangyi.utils.JsOperation;
import com.shangyi.utils.NetUtil;
import com.shangyi.utils.SystemUtilts;
import com.shangyi.utils.ToastUtil;
import com.tencent.smtt.sdk.ValueCallback;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

import java.io.File;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * Created by Administrator on 2016/7/23.
 */
public class LoadUriActivity extends BaseActivity {
    @BindView(R.id.pb_line_setting)
    ProgressBar pbLine;
    @BindView(R.id.webview_setting)
    WebView webView;
    private Activity activity;
    private Context context;
    private String openTitle;
    private String openUri;
    private static final String TAG=LoadUriActivity.class.getSimpleName();

    private final static int FILECHOOSER_RESULTCODE = 1;
    private android.webkit.ValueCallback<Uri[]> mUploadCallbackAboveL;
    private ValueCallback<Uri> mUploadMessage;
    private Uri imageUri;

    private String phoneManufacturer;//手机厂商



    @Override
    protected void findViewById() {
        setContentView(R.layout.act_setting);
        ButterKnife.bind(this);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        activity = LoadUriActivity.this;
        context = this;
        phoneManufacturer = SystemUtilts.getPhoneManufacturer();
        SyLog.d("phoneMdel", phoneManufacturer);
        Intent intent = getIntent();
        openTitle = intent.getStringExtra(Contants.WebUrl.OPEN_TITLE);
        openUri = intent.getStringExtra(Contants.WebUrl.OPEN_URI);
        setTitleText(openTitle);
        showWebView();

    }

    @SuppressLint("JavascriptInterface")
    private void showWebView() {
        try {
            webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setDefaultTextEncodingName("utf-8");
            webView.addJavascriptInterface(new JsOperation(activity, context), "jsObj");
            webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
            webView.loadUrl(openUri);
            webView.getSettings().setDomStorageEnabled(true);
            webView.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                    if (url.startsWith("http:") || url.startsWith("https:")) {
                        return false;
                    }
                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                    startActivity(intent);
                    return true;
                }

                @Override
                public void onReceivedError(WebView webView, int i, String s, String s1) {
                    super.onReceivedError(webView, i, s, s1);
                    if (NetUtil.isConnectivity(LoadUriActivity.this)) {
                        ToastUtil.defaultToast(getApplicationContext(), getString(R.string.common_network_data_error));
                        webView.loadUrl("file:///android_asset/nonetwork/data_error.html");
                    } else {
                        ToastUtil.defaultToast(getApplicationContext(), getString(R.string.common_network_is_null));
                        webView.loadUrl("file:///android_asset/nonetwork/nonetwork.html");
                    }

                }
            });
            webView.setWebChromeClient(new WebChromeClient() {
                @Override
                public void onProgressChanged(WebView webView, int newProgress) {
                    super.onProgressChanged(webView, newProgress);
                    if (newProgress >= 100) {
                        pbLine.setVisibility(View.GONE);
                    }
                }

                public void openFileChooser(ValueCallback<Uri> uploadMsg) {
                    SyLog.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg)");
                    mUploadMessage = uploadMsg;
                    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                    i.addCategory(Intent.CATEGORY_OPENABLE);
                    i.setType("image/*");
                    LoadUriActivity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
                }
                public void openFileChooser( ValueCallback uploadMsg, String acceptType ) {
                    SyLog.d(TAG, "openFileChoose( ValueCallback uploadMsg, String acceptType )");
                    mUploadMessage = uploadMsg;
                    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                    i.addCategory(Intent.CATEGORY_OPENABLE);
                    i.setType("image/*");
                    LoadUriActivity.this.startActivityForResult(
                            Intent.createChooser(i, "File Browser"),
                            FILECHOOSER_RESULTCODE);
                }
                public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
                    SyLog.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
                    mUploadMessage = uploadMsg;
                    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                    i.addCategory(Intent.CATEGORY_OPENABLE);
                    i.setType("image/*");
                    LoadUriActivity.this.startActivityForResult( Intent.createChooser( i, "File Browser" ), LoadUriActivity.FILECHOOSER_RESULTCODE );
                }

                // For Android 5.0+
                public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
                    mUploadCallbackAboveL = filePathCallback;
                    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                    i.addCategory(Intent.CATEGORY_OPENABLE);
                    i.setType("image/*");
                    LoadUriActivity.this.startActivityForResult(
                            Intent.createChooser(i, "File Browser"),
                            FILECHOOSER_RESULTCODE);
                    return true;
                }
            });

            /**
             * 屏蔽长按事件
             */
            webView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    return true;
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==FILECHOOSER_RESULTCODE)
        {
            if (null == mUploadMessage && null == mUploadCallbackAboveL) return;
            Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
            if (mUploadCallbackAboveL != null) {
                onActivityResultAboveL(requestCode, resultCode, data);
            }
            else  if (mUploadMessage != null) {
                mUploadMessage.onReceiveValue(result);
                mUploadMessage = null;
            }
        }
    }
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void onActivityResultAboveL(int requestCode, int resultCode, Intent data) {
        if (requestCode != FILECHOOSER_RESULTCODE
                || mUploadCallbackAboveL == null) {
            return;
        }
        Uri[] results = null;
        if (resultCode == Activity.RESULT_OK) {
            if (data == null) {
            } else {
                String dataString = data.getDataString();
                ClipData clipData = data.getClipData();
                if (clipData != null) {
                    results = new Uri[clipData.getItemCount()];
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                }
                if (dataString != null)
                    results = new Uri[]{Uri.parse(dataString)};
            }
        }
        mUploadCallbackAboveL.onReceiveValue(results);
        mUploadCallbackAboveL = null;
        return;
    }

    /**
     * webView重载当前地址
     */
    public void refreshWebView() {
        runOnUiThread(new Runnable() {//否则会提示运行在不同的进程
            @Override
            public void run() {
                webView.loadUrl(openUri);
            }
        });
    }

    @Override
    protected void onRestart() {
        super.onRestart();
//        webView.loadUrl(openUrl);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        webView.clearCache(true);
        webView.clearHistory();

    }

    @Override
    public void onResume() {
        super.onResume();
        webView.getSettings().setJavaScriptEnabled(true);
    }

    @Override
    protected void onStop() {
        super.onStop();
        webView.getSettings().setJavaScriptEnabled(false);
    }

    /**
     * 调用此方法结束自己
     */
    public void goDestory() {
        activity.finish();
        ActivityCollector.finishAll();
    }

    @Override
    protected void setListener() {

    }
}

此类就是一个传入title和url,用Activity加载

Vue.js是一个流行的前端框架,它使得构建用户界面变得更加简单。Vant是一个轻量级的移动UI组件库,其中包括Vant Uploader组件,这个组件允许你在Android应用中通过Webview展示件上传功能。 当使用Vant Uploader在Android Webview中让用户选择照片时,通常会借助设备原生的件选择器,这涉及到浏览器与设备操作系统的交互。Android系统提供了选择照片的API,比如`Intent` API,可以创建一个意图(Intent),指定`ACTION_GET_CONTENT`或者`ACTION_PICK_IMAGE`, 来弹出一个可以选择相册打开相机的对话框。你需要在Android端处理这部分逻辑,JavaScript端则通过WebView调用相应的JavaScript Bridge(如cordova、vux等提供的bridge)来触发这个选择图片的动作,并接收用户的选取结果。 以下是大概的步骤: 1. Android端: - 创建一个Intent,指定ACTION_PICK_IMAGE或ACTION_GET_CONTENT。 - 调用startActivityForResult启动该Intent,传递给Webview对应的JavaScript函数。 2. Vue.js (Webview端): - 定义一个事件处理器,等待从Android发起的JS-RPC调用,例如 `window.webkit.messageHandlers.chooseImage.postMessage()`。 - 当接收到消息时,显示选择图片的提示,并处理用户的选择结果,可能是一个路径或者件对象。 ```javascript // 假设你已经设置了一个名为"chooseImage"的消息处理器 document.getElementById('webview').addEventListener('message', function(e) { const type = e.data.type; if (type === 'openImagePicker') { // 显示选择图片的对话框 let result = /* 等待用户选择的结果 */; // 将结果发送回Android端 window.webkit.messageHandlers.chooseImage.postMessage(result); } }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值