You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用getUserMedia获取视频流安卓真机报NotReadableError问题求助

解决Cordova中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:07:34