我想在Android WebView的PWA中使用QR码扫描仪。
PWA在chrome浏览器上可以正常工作。
我确实有在“应用程序”->“应用程序名称”->“权限”下设置摄像机的权限
minSdkVersion 26和targetSdkVersion 28
在装有Android 9的华为手机上测试
问题是似乎没有授予该权限。 另外,许可请求被重复多次。
Android代码
表现
android:name="android.hardware.camera"
android:required="true" />
根据上一个问题的答案,我在WebViewHelper类中有此代码
lateinit var webkitPermissionRequest : PermissionRequest
...
webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
webkitPermissionRequest = request
val requestedResources = request.resources
for (r in requestedResources) {
if (r == PermissionRequest.RESOURCE_VIDEO_CAPTURE) {
// In this sample, we only accept video capture request.
val alertDialogBuilder = AlertDialog.Builder(activity)
.setTitle("Allow Permission to camera")
.setPositiveButton("Allow") { dialog, which ->
dialog.dismiss()
webkitPermissionRequest.grant(arrayOf(PermissionRequest.RESOURCE_VIDEO_CAPTURE))
Log.d(TAG, "Granted")
}
.setNegativeButton("Deny") { dialog, which ->
dialog.dismiss()
webkitPermissionRequest.deny()
Log.d(TAG, "Denied")
}
val alertDialog = alertDialogBuilder.create()
alertDialog.show()
break
}
}
}
...
}
日志:授予权限后,将再次请求(多次)
D/WebViewHelper: Granted
V/InputMethodManager: Reporting focus gain, without startInput
I/PermissionManager: camera remind result:true
I/CameraManager: open camera: 1, package name: "myApp"
I/BackgroundPermManager: pkgName: "myApp", pid: 31365 ,uidOf3RdApk: 10197 ,permType: 0 ,permCfg: 1
I/HwCameraUtil: notifySurfaceFlingerCameraStatus : isFront = true , isOpend = true
I/HwCameraUtil: notifySurfaceFlingerFrontCameraStatus 8011 transact success!
E/cr_VideoCapture: CameraDevice.StateCallback onOpened
I/WebViewHelper: onPermissionRequest
onPermissionRequest
这似乎是问题所在
I/GRALLOC: LockFlexLayout: baseFormat: 11, yStride: 640, ySize: 307200, uOffset: 307200, uStride: 640
E/ion: ioctl c0044901 failed with code -1: Invalid argument
I/chromium: "Unhandled rejection", source: "PWA
"Uncaught (in promise) NotAllowedError: play() can only be initiated by a user gesture.", source: "PWA"
最后,此错误重复出现(无限期)
I/GRALLOC: LockFlexLayout: baseFormat: 11, yStride: 640, ySize: 307200, uOffset: 307200, uStride: 640
JavaScript代码
JS端的代码可以很好地工作,直到在WebView中打开为止。
app.ports.scanQR.subscribe(() => {
// Delay until page loaded
setTimeout(function(){
const video = document.getElementById('media-video');
function returnResult(result) {
app.ports.onGotQR.send(result);
scanner.destroy();
}
const scanner = new QrScanner(video, result => returnResult(result));
scanner.start();
}, 50);
});
}
如果我直接致电getUserMedia,问题仍然存在
if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true })
.then(function (stream) {
video.srcObject = stream;
})
.catch(function (err0r) {
console.log("Something went wrong!");
});
}
取得相机的「应用程式」权限:
在WebviewHelper.kt中
webView.webChromeClient = object : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest) {
Log.i(TAG, "onPermissionRequest")
// grants permission for app. video not showing
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED
) {
Log.i(TAG, "Request Permission")
requestPermissions(activity, arrayOf(Manifest.permission.CAMERA), 1010)
} else {
Log.i(TAG, "Permission already granted")
}
...
}
在MainActivity.kt中
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
when (requestCode) {
cameraRequestCode -> {
Log.d("MainActivity", "onRequestPermissionsResult: Camera Request")
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
Log.d("MainActivity", "Camera Request: Permission granted")
// permission was granted, yay!
} else {
// permission denied, boo!
Log.d("MainActivity", "Camera Request: Permission denied")
}
return
}
...
授予相机的“应用程序”权限后,将按预期结果显示以下日志:
D/MainActivity: onRequestPermissionsResult: Camera Request
Camera Request: Permission granted