小工具知识网

当前位置: 首页 > 行业知识 > Android webview加载页面获取摄像头(h5页面中含有扫描二维码功能)

行业知识

Android webview加载页面获取摄像头(h5页面中含有扫描二维码功能)

2026-11-09 17:37:09 来源:互联网转载

场景介绍:

Android app中的webview加载含摄像头相关逻辑的H5页面,进行赋权的操作

H5页面调取摄像头识别二维码逻辑:

vue编写

                                        {{ trackStatus ? '关闭闪光灯' : '打开闪光灯' }}                import { nextTick, ref } from 'vue'import jsQr from 'jsqr'const emit = defineEmits(['success'])interface IProps {  /** 使用后置还是前置摄像头 */  exact?: 'environment' | 'user'  /** 获取摄像头视频像素 false 正常, true高清 */  definition?: boolean  /** 是否持续监听 */  continue?: boolean}const props = withDefaults(defineProps(), {  exact: 'environment',  definition: false,  continue: false})if (origin.indexOf('https') === -1) throw '请在 https 环境中调用摄像头。'const canvasRef = ref()const windowWidth = document.documentElement.clientWidth || document.body.clientWidthconst windowHeight = document.documentElement.clientHeight || document.body.clientHeightlet video: HTMLVideoElement,  canvas2d: CanvasRenderingContext2D,  stream: MediaStream,  track: MediaStreamTrack,  isUseTorch = ref(false)const trackStatus = ref(false)nextTick(() => {  video = document.createElement('video')  video.setAttribute('playsinline', 'true')  video.setAttribute('webkit-playsinline', 'true')  video.width = windowWidth  video.height = windowHeight  canvasRef.value!.width = windowWidth  canvasRef.value!.height = windowHeight  canvas2d = canvasRef.value!.getContext('2d')!  openScan()})async function openScan() {  const width = transtion(windowHeight)  const height = transtion(windowWidth)  const videoParam = {    audio: false,    video: {      facingMode: { exact: props.exact },      width,      height    }  }  try {    stream = await navigator.mediaDevices.getUserMedia(videoParam)    video.srcObject = stream    video.play()    tick()    track = stream.getVideoTracks()[0]    setTimeout(() => {      const t: any = track.getCapabilities()      isUseTorch.value = t.torch || null    }, 500)  } catch (error) {    console.log('设备不支持,请检查是否允许摄像头权限', error)    throw error  }}function tick() {  if (video.readyState === video.HAVE_ENOUGH_DATA) {    canvas2d.drawImage(video, 0, 0, windowWidth, windowHeight)    const imageData = canvas2d.getImageData(0, 0, windowWidth, windowHeight)    const codeRes = jsQr(imageData.data, imageData.width, imageData.height, {      inversionAttempts: 'dontInvert'    })    if (codeRes) {      drawLine(codeRes.location.topLeftCorner, codeRes.location.topRightCorner, '#FF3B58')      drawLine(codeRes.location.topRightCorner, codeRes.location.bottomRightCorner, '#FF3B58')      drawLine(codeRes.location.bottomRightCorner, codeRes.location.bottomLeftCorner, '#FF3B58')      drawLine(codeRes.location.bottomLeftCorner, codeRes.location.topLeftCorner, '#FF3B58')      if (codeRes.data) {        getData(codeRes.data)      }    }  }  requestAnimationFrame(tick)}interface Point {  x: number  y: number}function drawLine(begin: Point, end: Point, color: string) {  canvas2d.beginPath()  canvas2d.moveTo(begin.x, begin.y)  canvas2d.lineTo(end.x, end.y)  canvas2d.lineWidth = 4  canvas2d.strokeStyle = color  canvas2d.stroke()}function getData(data: string) {  emit('success', data)  if (!props.continue) return closeCamera()}function closeCamera() {  if (stream) {    stream.getTracks().forEach((track) => {      track.stop()    })  }}function transtion(number: number) {  return props.definition ? number * 1.6 : number}const openTrack = () => {  trackStatus.value = !trackStatus.value  const ww: any = {    advanced: [{ torch: trackStatus.value }]  }  track.applyConstraints(ww)}

问题:在app端访问时,扫描摄像头直接出不来显示无权限。

Android部分:

一:AndroidManifest.xml部分

新增相关权限

                        

一:webview部分

1,首先在webview 的 initview 方法中添加如下方法

XXPermissions.with(this)        .permission(Permission.READ_EXTERNAL_STORAGE,                Permission.WRITE_EXTERNAL_STORAGE, Permission.CAMERA)        .request(new PermissionCallback() {            @Override            public void onGranted(List permissions, boolean all) {                      }            @Override            public void onDenied(List permissions, boolean never) {                super.onDenied(permissions, never);               }        });

2,需要在 BrowserChromeClient 方法中添加如下方法

   @RequiresApi(Build.VERSION_CODES.LOLLIPOP)        @Override        public void onPermissionRequest(android.webkit.PermissionRequest request) {            System.out.println("onPermissionRequest");            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {                request.grant(request.getResources());            }        }

上一篇:算法D14 | 二叉树1 | 144. 二叉树的前序遍历 145. 二叉树的后序遍历 94. 二叉树的中序遍历

下一篇:中学英文怎么读语音?