Android混合开发之WebView调用相机


前言

最近有一个需求:H5通过标题input标签调用Android系统相机、相册的功能

一、H5页面的使用方式

<input type="file" accept="image/*" capture>
<input type="file" accept="video/*" capture>

根据不同的accept的值,分别调用拍摄图片、录制视频的功能

二、Android提供的支持

1.WebView基本属性设置

/**
* 初始化WebView配置
 */
private void initWebView() {
    
    

    WebSettings settings = webView.getSettings();
    //设置webview支持javascript
    settings.setJavaScriptEnabled(true);
    //增加 设置脚本是否允许自动打开弹窗
    settings.setJavaScriptCanOpenWindowsAutomatically(true);
    //支持自动加载图片
    settings.setLoadsImagesAutomatically(true);
    //设置webview推荐使用的窗口,使html界面自适应屏幕
    settings.setUseWideViewPort(true);
    settings.setLoadWithOverviewMode(true);
    //设置webview保存表单数据
    settings.setSaveFormData(true);
    //设置webview保存密码
    settings.setSavePassword(true);


    int mDensity = getResources().getDisplayMetrics().densityDpi;
    if (mDensity == 120) {
    
    
        settings.setDefaultZoom(WebSettings.ZoomDensity.CLOSE);
    } else if (mDensity == 160) {
    
    
        settings.setDefaultZoom(WebSettings.ZoomDensity.MEDIUM);
    } else if (mDensity == 240) {
    
    
        settings.setDefaultZoom(WebSettings.ZoomDensity.FAR);
    }
    //支持缩放
    settings.setSupportZoom(true);
    settings.setSupportMultipleWindows(true);
    //设置APP可以缓存
    settings.setAppCacheEnabled(true);
    settings.setDatabaseEnabled(true);
    //返回上个界面不刷新  允许本地缓存
    settings.setDomStorageEnabled(true);
    //增加 设置缓存LOAD_DEFAULT   LOAD_CACHE_ONLY,LOAD_NO_CACHE
    settings.setCacheMode(WebSettings.LOAD_DEFAULT);
    // 设置可以访问文件
    settings.setAllowFileAccess(true);
    //不支持放大缩小
    settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
    //不支持放大缩小
    settings.setDisplayZoomControls(false);

    //增加 设置编码格式
    settings.setDefaultTextEncodingName("utf-8");

    webView.setLongClickable(true);
    webView.setScrollbarFadingEnabled(true);
    webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
    webView.setDrawingCacheEnabled(true);
}

2.WebView实现调用相机的支持

 webView.setWebChromeClient( new WebChromeClient(){
    
    
  /**
   * For Android > 4.1.1
   * @param uploadMsg
   * @param mediaType
   * @param capture
   */
  public void openFileChooser(ValueCallback<Uri> uploadMsg , String mediaType, String capture) {
    
    
 		//该字段是一个callback方法,用来回传给H5,用户选择或者拍摄的照片的URI路径
      mUploadCallBackBelowL = uploadMsg;
      	//这里的mediaType就是 H5中传入的"image/*"或者"video/*"
      if(!TextUtils.isEmpty(mediaType)){
    
    
       	//根据不同的mediaType,做不同的操作 调用相机或者相册或者录像机
         ...
      }
  }

  /**
   * Android 5.0
   * @param webView
   * @param filePathCallback
   * @param fileChooserParams
   * @return
   */
  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
  public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
                                   FileChooserParams fileChooserParams) {
    
    
      //该字段是一个callback方法,用来回传给H5,用户选择或者拍摄的照片的URI路径
      mUploadCallbackAboveL = filePathCallback;
      //解析h5的调用参数
      if (fileChooserParams != null && fileChooserParams.getAcceptTypes() != null
              && fileChooserParams.getAcceptTypes().length > 0) {
    
    
          //这里的mediaType就是 H5中传入的"image/*"或者"video/*"
          String mediaType = fileChooserParams.getAcceptTypes()[0];
          if(!TextUtils.isEmpty(mediaType)){
    
    
          	//根据不同的mediaType,做不同的操作 调用相机或者相册或者录像机
             ...
             //TODO 注意,这里一定要回传true,H5才能会处理mUploadCallbackAboveL返回的值
             return true;
          }
      }
      return false;
  }
});

接下来当拍摄或者录像完成后,要回传对应的文件的Uri给H5

/**
 * 调用回掉方法,传参给H5页面
 * @param url
 */
private void doCallback(Uri url){
    
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    
    
        if (mUploadCallbackAboveL != null) {
    
    
            Uri[] result = {
    
    url};
            mUploadCallbackAboveL.onReceiveValue(result);
            mUploadCallbackAboveL = null;
        }
    } else {
    
    
        if (mUploadCallBackBelowL != null) {
    
    
            mUploadCallBackBelowL.onReceiveValue(url);
            mUploadCallBackBelowL = null;
        }
    }
    mMediaType = "";
}

3.实现调用相机的代码

调用相机、录像机、图库的代码传送门

总结

1)关键点在于重写setWebChromeClient的onShowFileChooser()方法,并且返回true
2)显式的通过mUploadCallbackAboveL回调方法,将Uri传递给H5页面

猜你喜欢

转载自blog.csdn.net/dirksmaller/article/details/108214341