Cordova安卓混合应用中navigator.mediaDevices.getUserMedia调用相机问题
首先直接给你结论:完全可以实现,但在Android 5.1(API 22)这种旧版本系统和模拟器环境下,确实存在几个容易踩的坑,你遇到的问题大概率是WebView支持不足和模拟器配置导致的,下面一步步给你解决:
1. 先明确:Web API与Cordova插件的区别
你提到添加了cordova-plugin-camera插件,但其实navigator.mediaDevices.getUserMedia是标准Web API,和这个原生插件是两套独立的方案——如果你想用Web API直接获取相机流来实时预览(比如做扫码、实时滤镜),不需要依赖这个插件,甚至它可能和Web API的权限逻辑产生冲突,建议先移除这个插件试试:
cordova plugin remove cordova-plugin-camera
2. 解决Android 5.1 WebView的API支持问题
Android 5.1的系统默认WebView对navigator.mediaDevices的支持非常有限,它只支持旧版的navigator.getUserMedia回调写法,而且部分设备可能需要额外配置。最稳妥的办法是用Crosswalk WebView插件替换系统WebView,它基于Chromium,对现代Web API支持更完善:
cordova plugin add cordova-plugin-crosswalk-webview
安装后重新编译应用,WebView的兼容性会大幅提升。
3. 正确配置权限(不要直接改AndroidManifest.xml)
Cordova编译时会自动生成/覆盖AndroidManifest.xml,所以直接修改这个文件的配置会被覆盖,必须在项目根目录的config.xml里添加权限配置:
<platform name="android"> <!-- 相机权限及硬件特性声明 --> <config-file parent="/*" target="AndroidManifest.xml"> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" android:required="true" /> <uses-feature android:name="android.hardware.camera.autofocus" /> </config-file> </platform>
这样编译后权限才会被正确写入到最终的AndroidManifest.xml中。
4. 适配旧API的代码写法
即使替换了WebView,为了兼容Android 5.1的环境,建议同时兼容新旧API的写法,避免只使用Promise版的navigator.mediaDevices.getUserMedia:
function initCamera() { const videoElement = document.getElementById('camera-preview'); const constraints = { video: { facingMode: 'environment' } }; // 优先调用后置摄像头 // 优先使用现代API if (navigator.mediaDevices?.getUserMedia) { navigator.mediaDevices.getUserMedia(constraints) .then(stream => { videoElement.srcObject = stream; videoElement.play().catch(err => console.error("播放预览失败:", err)); }) .catch(err => console.error("现代API调用失败:", err)); } // 兼容旧版API else if (navigator.getUserMedia) { navigator.getUserMedia(constraints, stream => { // 旧WebView需要用createObjectURL来设置视频源 videoElement.src = window.URL.createObjectURL(stream); videoElement.play(); }, err => console.error("旧版API调用失败:", err) ); } else { alert("当前设备不支持相机访问"); } }
5. 解决模拟器的摄像头识别问题
Android 5.1的模拟器对外部摄像头(比如你的笔记本摄像头)的支持确实很差,建议按以下步骤排查:
- 打开模拟器的Extended Controls(右侧边栏的三个点图标),进入
Camera选项卡,将前置/后置摄像头都设置为你的笔记本摄像头(比如Webcam0) - 重启模拟器,确保摄像头设置生效
- 如果还是不行,直接用真实的Android 5.1设备测试——模拟器的相机模拟本身就有很多bug,真实设备的结果更准确
总结
navigator.mediaDevices.getUserMedia完全可以在Cordova安卓混合应用中使用,你遇到的问题主要是旧版本Android的WebView兼容性和模拟器配置导致的,按照上面的步骤逐一排查,应该就能解决。
内容的提问来源于stack exchange,提问作者Arioch

