You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Cordova开发安卓应用:不调用系统默认相机获取摄像头流失败问题求助

解决Cordova安卓端获取摄像头流不调用系统相机的问题

我之前在Cordova开发安卓应用时也踩过这个坑,Windows上的Web API在安卓WebView里确实有不少兼容性问题,尤其是摄像头相关的。下面给你两种可行的解决方案,按需选择:

方案一:使用专门的Cordova摄像头预览插件(推荐)

如果你不想调用系统相机,cordova-plugin-camera-preview是最佳选择——它专门做应用内的摄像头实时预览,支持拍照、切换前后摄像头,完全符合你的需求,而且兼容性比原生getUserMedia好太多。

步骤:

  1. 安装插件
cordova plugin add cordova-plugin-camera-preview
  1. 初始化预览并拍照的示例代码
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

火山引擎 最新活动