前言
最近有一个需求: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页面