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

Xamarin Community Toolkit CameraView拍照触发CAMERA_ERROR(3)问题求助

相机预览页MediaCaptured事件未触发及CAMERA_ERROR(3)问题排查解决

问题场景

使用Xamarin Community Toolkit的CameraView组件开发跨平台相机预览页,拍照时Debug输出显示"camera picture taken",但MediaCaptured事件未触发,无该方法内的日志输出;拍照后出现错误:

[0:] CameraView: Error camera access
ErrorMessage: CAMERA_ERROR (3): The camera device has encountered a serious error.

已尝试重启应用、模拟器及更换设备,问题仍存在。

相关代码

XAML代码

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Test.CameraPreview"
             
             NavigationPage.HasBackButton="True"
             NavigationPage.HasNavigationBar="False">
    <ContentPage.Content>
        <Grid x:Name="cameraGrid">
            <xct:CameraView x:Name="xctCameraView"
                            CaptureMode="Photo"
                            MediaCaptured="MediaCaptured"
                            HorizontalOptions="FillAndExpand"
                            VerticalOptions="FillAndExpand"/>
            <StackLayout VerticalOptions="EndAndExpand">
                <StackLayout Orientation="Horizontal" HorizontalOptions="CenterAndExpand" BackgroundColor="Transparent">
                    <Frame CornerRadius="15" x:Name="videoFrame" WidthRequest="48" Padding="7">
                        <Label Text="Video" HorizontalOptions="CenterAndExpand" x:Name="videoLabel" BackgroundColor="Transparent"/>
                    </Frame>
                    <Frame CornerRadius="15" x:Name="pictureFrame" WidthRequest="48" Padding="7">
                        <Label Text="Picture" HorizontalOptions="CenterAndExpand" x:Name="pictureLabel" BackgroundColor="Transparent"/>
                    </Frame>
                </StackLayout>
                <ImageButton Clicked="CapturePhoto" HeightRequest="120" WidthRequest="120"
                             HorizontalOptions="Center" x:Name="captureBtn" BackgroundColor="Transparent"/>
            </StackLayout>
        </Grid>
    </ContentPage.Content>
</ContentPage>

C#代码

private void CapturePhoto(object sender, EventArgs e)
{
    if (isPictureSelected)
    {
        if (xctCameraView != null)
        {
            Debug.WriteLine($"xctCameraView is not null");
            xctCameraView.Shutter();
            Debug.WriteLine($"camera picture taken");
        }
        else
        {
            DisplayAlert("Error", "Camera view is not available.", "OK");
        }
    }
}

private void MediaCaptured(object sender, MediaCapturedEventArgs e)
{
    switch (xctCameraView.CaptureMode)
    {
        default:
        case CameraCaptureMode.Default:
        case CameraCaptureMode.Photo:
            Debug.WriteLine($"media captured is passed");
            if (e.Image != null)
            {
                Debug.WriteLine($"e.Image is not null");
                var imageSource = (StreamImageSource)e.Image;
                using (var stream = imageSource.Stream(CancellationToken.None).Result)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        Debug.WriteLine($"var memoryStream = new MemoryStream() went through");
                        stream.CopyTo(memoryStream);
                        photoData = memoryStream.ToArray();
                        Debug.WriteLine($"navigating to EditPostPage");
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            Navigation.PushAsync(new EditPostPage(userId, textId, photoData));
                        });
                    }
                }
            }
            break;
        case CameraCaptureMode.Video:
            break;
    }
}

排查原因及解决办法

1. 相机权限未正确配置

跨平台应用必须在各平台项目中声明相机权限,否则相机无法正常访问:

  • Android:在AndroidManifest.xml中添加权限
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    
    同时在页面OnAppearing中动态请求权限(Android 6.0+):
    protected override async void OnAppearing()
    {
        base.OnAppearing();
        var status = await Permissions.CheckStatusAsync<Permissions.Camera>();
        if (status != PermissionStatus.Granted)
        {
            status = await Permissions.RequestAsync<Permissions.Camera>();
            if (status != PermissionStatus.Granted)
            {
                DisplayAlert("权限不足", "需要相机权限才能使用拍照功能", "确定");
                return;
            }
        }
        xctCameraView.IsEnabled = true;
    }
    
  • iOS:在Info.plist中添加相机权限描述
    <key>NSCameraUsageDescription</key>
    <string>需要访问相机进行拍照</string>
    

2. CameraView初始化时机问题

调用Shutter()时相机可能未完成初始化,导致拍照失败且事件不触发:

  • 在页面OnAppearing中等待相机初始化完成:
    protected override async void OnAppearing()
    {
        base.OnAppearing();
        // 先执行权限检查
        xctCameraView.IsEnabled = true;
        await Task.Delay(500); // 等待相机资源加载
        if (!xctCameraView.IsAvailable)
        {
            DisplayAlert("错误", "相机初始化失败", "确定");
        }
    }
    
  • 在CapturePhoto中增加可用状态检查:
    private void CapturePhoto(object sender, EventArgs e)
    {
        if (isPictureSelected && xctCameraView?.IsAvailable == true)
        {
            Debug.WriteLine($"xctCameraView is available");
            xctCameraView.Shutter();
            Debug.WriteLine($"camera picture taken");
        }
        else
        {
            DisplayAlert("Error", "Camera view is not available.", "OK");
        }
    }
    

3. 相机资源未正确释放

页面销毁时未释放相机资源,导致资源冲突触发错误:

  • 在页面OnDisappearing中禁用相机:
    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        xctCameraView.IsEnabled = false;
    }
    

4. 异步代码死锁问题

MediaCaptured中使用.Result会导致死锁,改用await处理:
修改为异步方法:

private async void MediaCaptured(object sender, MediaCapturedEventArgs e)
{
    switch (xctCameraView.CaptureMode)
    {
        default:
        case CameraCaptureMode.Default:
        case CameraCaptureMode.Photo:
            Debug.WriteLine($"media captured is passed");
            if (e.Image != null)
            {
                Debug.WriteLine($"e.Image is not null");
                var imageSource = (StreamImageSource)e.Image;
                using (var stream = await imageSource.Stream(CancellationToken.None))
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        Debug.WriteLine($"var memoryStream = new MemoryStream() went through");
                        await stream.CopyToAsync(memoryStream);
                        photoData = memoryStream.ToArray();
                        Debug.WriteLine($"navigating to EditPostPage");
                        await Navigation.PushAsync(new EditPostPage(userId, textId, photoData));
                    }
                }
            }
            break;
        case CameraCaptureMode.Video:
            break;
    }
}

5. 版本兼容性问题

检查Xamarin Community Toolkit与Xamarin.Forms版本是否兼容,升级至最新稳定版:

  • 更新NuGet包:确保Xamarin.CommunityToolkit和Xamarin.Forms都使用最新稳定版本,避免版本不匹配导致组件异常。

内容的提问来源于stack exchange,提问作者bluedra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:25:06