前言
安卓原生组件webview加载h5的URL,若要h5调用安卓原生相机和相册有效需要做以下操作。
测试机:魅蓝note2 系统5.1.1
华为荣耀畅玩7x 系统8.0.0
一、h5页面相关
方便与安卓原生代码相对应且拿到相对应的file值,避免之后不必要的不匹配麻烦。
1、标签设置 [相机、相册]
<input type="file" accept="image/*" capture="camera">
<input type="file" accept="image/*" >
2、函数代码
(1)js方法,使用FormData方法避免安卓端兼容更多的机型
// 实例化一个空对象
var data = new FormData();
//获取file文件
var file=document.getElementById(yourInputId).files[0];
//将文件加入到data中,一般FormData对象中添加数据使用append()方法
data.append(file)
// 创建一个HTTP请求
var request = new XMLHttpRequest();
// 然后使用open方法,选择传送的method和后台的URL
request.open("POST|GET", "URL");
// 最后,向后台发送我们的数据
request.send(data)
(2)如果是jquery写法如下
// 获取要传输的文件------假设只有一个文件
var file = document.getElementById(yourInputId).files[0];
// ajax传输
$.ajax({
url: URL,
type: "POST",
async: false,
cache: false,
processData: false,// 告诉jQuery不要去处理发送的数据
contentType: false,// 告诉jQuery不要去设置Content-Type请求头
data: file,
success: function(data){
alert(data);
},
error: function(err) {
alert(err);
}
});
二、Android端原生相关
(1)webview配置
WebSettings settings = webView.getSettings();
//开启JavaScript支持
settings.setJavaScriptEnabled(true);
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
settings.setAppCacheEnabled(false);
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
settings.setDomStorageEnabled(true);
settings.setDefaultTextEncodingName("UTF-8");
settings.setAllowContentAccess(true); //是否可访问Content Provider的资源,默认值 true
settings.setAllowFileAccess(true); //是否可访问本地文件,默认值 true
//是否允许通过file url加载的Javascript读取本地文件,默认值 false
settings.setAllowFileAccessFromFileURLs(false);
//是否允许通过file url加载的Javascript读取全部资源(包括文件,http,https),默认值 false
settings.setAllowUniversalAccessFromFileURLs(false);
//支持缩放
settings.setSupportZoom(true);
//辅助WebView设置处理关于页面跳转,页面请求等操作
webView.setWebViewClient(new MyWebViewClient());
//辅助WebView处理图片上传操作
webView.setWebChromeClient(new MyChromeWebClient());
//加载地址[你自己的加载url地址]
webView.loadUrl(loadUrl);
(2)自定义MyChromeWebClient辅助webview处理除视频外调用相机的图片上传操作,如上文的文件上传标签
private class MyChromeWebClient extends WebChromeClient {
// For Android 3.0-
@SuppressWarnings("static-access")
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
Log.i("MainNewActivity", "openFileChoose(ValueCallback<Uri> uploadMsg)");
mUploadMessage = uploadMsg;
if (videoFlag) {
recordVideo();
} else {
takePhoto();
}
}
// For Android 3.0+
@SuppressWarnings("static-access")
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
Log.d("MainNewActivity", "openFileChoose( ValueCallback uploadMsg, String acceptType )");
mUploadMessage = uploadMsg;
if (videoFlag) {
recordVideo();
} else {
takePhoto();
}
}
//For Android 4.1
@Override
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
Log.d("MainNewActivity", "openFileChoose(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
mUploadMessage = uploadMsg;
if (videoFlag) {
recordVideo();
} else {
takePhoto();
}
}
// For Android 5.0+
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
Log.d("MainNewActivity", "onShowFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
mUploadCallbackAboveL = filePathCallback;
if (videoFlag) {
recordVideo();
} else {
onenFileChooseImpleForAndroid(filePathCallback);
}
return true;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
progressbar.setVisibility(GONE);
} else {
if (progressbar.getVisibility() == GONE)
progressbar.setVisibility(VISIBLE);
progressbar.setProgress(newProgress);
}
super.onProgressChanged(view, newProgress);
}
}
1⃣ 其中调用录像功能相关代码
private void recordVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
//限制时长
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
//开启摄像机
startActivityForResult(intent, VIDEO_REQUEST);
}
2⃣ 其中调用安卓系统小于5.0的相机功能相关代码
private void takePhoto() {
File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/" + SystemClock.currentThreadTimeMillis() + ".jpg");
imageUri = Uri.fromFile(fileUri);
Intent cameraIntent = new Intent(MediaStore.ACTION_I