前言
在使用flutter_inappwebview时,H5中需要进行交互拍照、选择图片。但in_appwebview中实现的方式目前无法区分拍照还是选择图片。现在分析原因,看解决办法。
结论
先上结论
- H5中使用以下方式调用,一定要加上capture,表明希望通过捕获的方式获取照片,也就是拍照。
<input type="file" accept="image/*" capture>
- Android中的webview需要重写WebChromeClient类下的onShowFileChooser方法,才能实现拍照、图库的功能。
- 通过fileChooserParams.isCaptureEnabled()区分拍照还是图库。
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
boolean fromCamera = fileChooserParams.isCaptureEnabled();
}
问题分析
H5端
先从H5查看问题
<input type="file" accept="image/*">
为了表明想直接进入拍照,需要加上capture字段,由于android在5.0+无法准确区分capture后面的内容,所以加不加capture=“user”,在android上都是一样,只要有capture就行。
<input type="file" accept="image/*" capture>
Android-WebView端
由于android系统自带的webview默认是不支持拍照、图库功能,需要自己加入代码支持。重写onShowFileChooser方法,网上方法很多。
mWebView.setWebChromeClient(new WebChromeClient(){
public void openFileChooser(ValueCallback<Uri> valueCallback) {
}
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
}
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
boolean fromCamera = fileChooserParams.isCaptureEnabled();
String[] acceptTypes = fileChooserParams.getAcceptTypes();
Log.i("zzb", "fromCamera = " + fromCamera);
return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
}
});
旧的api是通过openFileChooser中的,这里的capture是个字符串,可以把h5中input中的capture=“user”、capture="environment"属性值带过去,但由于openFileChooser已经废弃。所以使用onShowFileChooser,但onShowFileChooser又没有capture字段,查看源码,发现有个类似方法,fileChooserParams.isCaptureEnabled()。在
<input capture />
中含有capture属性时,isCaptureEnabled()返回值为true,android官方isCaptureEnabled文档说明 但没有说明这个与原来openFileChooser方法中的capture关联关系,但从官方介绍看推测可以使用isCaptureEnabled来判断是否要直接打开摄像头。
在Inappwebview中存在的问题
- 无法直接进入拍照。
- 没有相机权限的时候并没有通知用户。
- 没有相机权限的时候,会直接进入到图库。
通过以上的结论,可以自己进行修改,如果有需要区分的功能,可以通过以上的方式对源码进行修改。
参考
测试html文件
<!DOCTYPE html>
<!-- 测试拍照和选择图片 -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Flutter InAppWebView</title>
<link rel="stylesheet" href="https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css">
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<link rel="shortcut icon" href="favicon.ico">
</head>
<body class="text-center" style="background-color:#cccccc">
<div>
普通输入没有capture字段: <input type="file" name="uploadfile">
</div>
<div>
属性中带有capture:<input type="file" accept="image/*" capture>
</div>
<div>
属性中带有capture="user":<input accept="image/*" capture="user" id="imgFile" name="imgFile" type="file">
</div>
<script src="js/main.js"></script>
</body>
</html>
|