使用getUserMedia获取视频流安卓真机报NotReadableError问题求助
我之前也踩过这个坑——模拟器里跑着一切正常,一到真实设备就报这个错,NotReadableError基本逃不开权限配置、硬件占用、WebView限制这几个核心问题,咱们一步步来解决:
1. 权限得自己盯紧:别依赖media-capture插件,手动搞定静态+动态授权
既然不想用cordova-plugin-media-capture,那权限这块就得自己做扎实,安卓的权限分静态声明和动态请求两步:
静态权限声明(config.xml)
先在platform/android节点下添加必要的权限和硬件特性,让系统明确知道你的应用需要摄像头:
<platform name="android"> <!-- 摄像头相关权限与特性 --> <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" /> <!-- 如果需要同时获取音频流,加上以下配置 --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-feature android:name="android.hardware.microphone" /> </platform>
动态权限请求(Android 6.0+)
安卓6.0以上的危险权限需要主动向用户请求,WebView原生的getUserMedia可能不会自动触发系统弹窗,所以得用cordova-plugin-android-permissions来手动处理:
先安装插件:
cordova plugin add cordova-plugin-android-permissions
然后在代码里先检查权限状态,再调用getUserMedia:
document.addEventListener("deviceready", onDeviceReady, false); function onDeviceReady() { const permissions = cordova.plugins.permissions; const cameraPerm = permissions.CAMERA; // 先检查当前权限状态 permissions.checkPermission(cameraPerm, (status) => { if (status.hasPermission) { // 有权限,初始化视频流 initVideoStream(); } else { // 无权限,请求用户授权 permissions.requestPermission(cameraPerm, (status) => { status.hasPermission ? initVideoStream() : alert("必须开启摄像头权限才能使用此功能"); }, (err) => console.error("请求权限失败:", err)); } }, (err) => console.error("检查权限失败:", err)); } function initVideoStream() { // 先从简单的约束开始,避免设备不支持高分辨率导致失败 const constraints = { video: true, audio: false }; navigator.mediaDevices.getUserMedia(constraints) .then(stream => { const videoEl = document.getElementById("your-video-element"); videoEl.srcObject = stream; videoEl.play(); }) .catch(err => { console.error("获取视频流失败:", err); if (err.name === "NotReadableError") { alert("无法访问摄像头!请检查:1. 是否有其他应用在占用摄像头;2. 系统设置里是否开启了应用的摄像头权限"); } }); }
2. 给WebView松绑:允许本地页面访问媒体资源
Cordova默认的WebView会对file://协议下的页面做限制,需要在config.xml里添加这些偏好设置,确保WebView能正常访问硬件:
<preference name="AllowFileAccess" value="true" /> <preference name="AllowUniversalAccessFromFileURLs" value="true" /> <preference name="MediaPlaybackRequiresUserAction" value="false" />
3. 排查硬件占用问题
真实设备上这个错误最常见的场景就是摄像头被其他应用占用——比如系统相机、微信视频通话、直播软件等等。可以在错误提示里引导用户关闭其他可能占用摄像头的应用后重试。
4. 适配定制ROM和旧系统
像小米、华为这类定制ROM会有额外的权限管控,即使代码里请求了权限,用户可能还需要手动去系统设置的「应用权限」里开启摄像头权限。另外,Android 5.0的系统WebView版本可能较低,建议用户在应用商店搜索「Android System WebView」更新到最新版本。
为什么模拟器没问题?
模拟器的摄像头是虚拟的,没有真实硬件的占用冲突,而且系统权限管控也更宽松,所以测试时容易成功,但真实设备的硬件和权限逻辑要复杂得多。
内容的提问来源于stack exchange,提问作者php_nub_qq

