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
相关产品推荐
相关产品推荐

