Cordova开发安卓应用:不调用系统默认相机获取摄像头流失败问题求助
解决Cordova安卓端获取摄像头流不调用系统相机的问题
我之前在Cordova开发安卓应用时也踩过这个坑,Windows上的Web API在安卓WebView里确实有不少兼容性问题,尤其是摄像头相关的。下面给你两种可行的解决方案,按需选择:
方案一:使用专门的Cordova摄像头预览插件(推荐)
如果你不想调用系统相机,cordova-plugin-camera-preview是最佳选择——它专门做应用内的摄像头实时预览,支持拍照、切换前后摄像头,完全符合你的需求,而且兼容性比原生getUserMedia好太多。
步骤:
- 安装插件
cordova plugin add cordova-plugin-camera-preview
- 初始化预览并拍照的示例代码
document.addEventListener('deviceready', function() { // 启动摄像头预览(全屏显示,后置摄像头) CameraPreview.startCamera({ x: 0, y: 0, width: window.screen.width, height: window.screen.height, camera: CameraPreview.CAMERA_DIRECTION.BACK, tapPhoto: true, // 点击预览区域拍照 toBack: true, // 让预览层在WebView下方,方便叠加自定义UI alpha: 1 }); // 绑定拍照按钮事件(如果不用tapPhoto的话) document.getElementById('take-photo-btn').addEventListener('click', function() { CameraPreview.takePicture({width: 1280, height: 960}, function(base64Img) { // 将照片显示在页面上 document.getElementById('photo-preview').src = `data:image/jpeg;base64,${base64Img}`; }, function(err) { console.error('拍照失败:', err); }); }); // 记得在退出页面时停止预览 // CameraPreview.stopCamera(); }, false);
这个插件不需要依赖WebView的getUserMedia支持,直接调用安卓原生摄像头API,所以不会出现NonReadableError的问题。
方案二:修复原生getUserMedia在安卓WebView的兼容性问题
如果你坚持要用标准的Web API,需要解决安卓WebView的权限和配置问题:
1. 确保动态申请相机权限
安卓6.0+要求动态申请危险权限,只在config.xml里声明是不够的,需要用插件主动请求:
- 安装权限插件:
cordova plugin add cordova-plugin-android-permissions
- 先请求权限再调用
getUserMedia:
document.addEventListener('deviceready', function() { const permissions = cordova.plugins.permissions; // 检查相机权限 permissions.checkPermission(permissions.CAMERA, function(status) { if (!status.hasPermission) { // 请求权限 permissions.requestPermission(permissions.CAMERA, function() { initCameraStream(); }, function() { alert('相机权限被拒绝,无法使用摄像头'); }); } else { initCameraStream(); } }); }, false); function initCameraStream() { if (!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia)) { alert("当前设备不支持摄像头"); return; } const video = document.querySelector("#capture-video video"); navigator.mediaDevices.getUserMedia({video: {facingMode: 'environment'}}) // 指定后置摄像头 .then((stream) => { video.srcObject = stream; video.play(); // 必须调用play()才能播放流 }) .catch(error => { console.error('摄像头访问失败:', error); alert(`错误信息:${error.message}`); }); }
2. 修正config.xml的WebView配置
在安卓平台的配置里添加这些偏好和权限设置,确保WebView支持媒体流:
<platform name="android"> <!-- 保留你已有的权限配置 --> <uses-feature android:name="android.hardware.camera" android:required="true" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 如果需要音频的话 --> <!-- WebView相关配置 --> <preference name="AndroidInsecureFileModeEnabled" value="true" /> <preference name="MediaPlaybackRequiresUserAction" value="false" /> <preference name="WebViewBounce" value="false" /> <!-- 启用硬件加速(摄像头流需要) --> <edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application/activity[@android:name='MainActivity']"> <activity android:name="MainActivity" android:windowSoftInputMode="adjustPan" android:hardwareAccelerated="true" /> </edit-config> </platform>
3. 更新Cordova安卓平台版本
尽量使用最新的cordova-android版本(比如v11+),新版本对WebRTC和媒体流的支持更完善,可以通过下面的命令更新:
cordova platform update android@latest
总结
优先推荐方案一的插件,因为它避开了WebView的兼容性坑,实现起来更稳定;如果一定要用标准API,就需要严格按照方案二的步骤配置权限和WebView参数。
内容的提问来源于stack exchange,提问作者broken chargingcable




