Blazor MAUI Hybrid应用无法调用移动设备相机求助
.NET MAUI Blazor Hybrid 调用移动设备相机解决方案
核心问题分析
你遇到的问题本质是Blazor Hybrid中直接使用Web端文件选择逻辑只会唤起文件管理器,无法触发原生相机;同时即使在AndroidManifest.xml中声明了权限,Android 6.0+仍需动态申请相机权限才能正常调用。
步骤1:修正权限配置
先清理AndroidManifest.xml中重复的权限,保留必要项:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- Android 13+ 需添加 --> <uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
步骤2:动态申请相机权限
在MAUI项目的MainActivity.cs中添加权限申请逻辑及回调处理:
using AndroidX.Core.App; using AndroidX.Core.Content; public class MainActivity : MauiAppCompatActivity { public static MainActivity Instance { get; private set; } public event EventHandler<PermissionResultArgs> PermissionResult; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Instance = this; } public async Task<bool> RequestCameraPermission() { var status = ContextCompat.CheckSelfPermission(this, Android.Manifest.Permission.Camera); if (status != Permission.Granted) { ActivityCompat.RequestPermissions(this, new[] { Android.Manifest.Permission.Camera }, 1001); var tcs = new TaskCompletionSource<bool>(); PermissionResult += (s, args) => { if (args.RequestCode == 1001) { tcs.SetResult(args.GrantResults[0] == Permission.Granted); } }; return await tcs.Task; } return true; } public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) { base.OnRequestPermissionsResult(requestCode, permissions, grantResults); PermissionResult?.Invoke(this, new PermissionResultArgs(requestCode, grantResults)); } } public class PermissionResultArgs : EventArgs { public int RequestCode { get; } public Permission[] GrantResults { get; } public PermissionResultArgs(int requestCode, Permission[] grantResults) { RequestCode = requestCode; GrantResults = grantResults; } }
步骤3:使用MediaPicker调用相机(推荐)
借助.NET MAUI Community Toolkit的MediaPicker组件,直接在Blazor页面中调用原生相机:
- 安装NuGet包:
CommunityToolkit.Maui - 在
MauiProgram.cs中注册组件:
builder.UseMauiApp<App>().UseMauiCommunityToolkit(); // 注册相机权限服务 builder.Services.AddSingleton<MainActivity>(MainActivity.Instance);
- 在Blazor页面中实现拍照逻辑:
@page "/camera" @inject IMediaPicker MediaPicker @inject MainActivity MainActivity <button @onclick="TakePhoto" class="btn btn-primary">拍摄照片</button> @if (photoPath != null) { <img src="@photoPath" alt="拍摄的照片" style="max-width: 100%;" /> } @code { string photoPath; async Task TakePhoto() { // 先检查并申请权限 var hasPermission = await MainActivity.RequestCameraPermission(); if (!hasPermission) { // 可添加权限申请失败提示 return; } if (MediaPicker.IsCaptureSupported) { var photo = await MediaPicker.CapturePhotoAsync(new MediaPickerOptions { Title = "拍摄照片" }); if (photo != null) { // 保存临时文件并获取本地路径 var localPath = Path.Combine(FileSystem.CacheDirectory, photo.FileName); using var stream = await photo.OpenReadAsync(); using var localStream = File.OpenWrite(localPath); await stream.CopyToAsync(localStream); photoPath = localPath; StateHasChanged(); } } } }
关键注意事项
- Android 13+ 必须添加
READ_MEDIA_IMAGES权限才能访问拍摄后的照片文件 - 不要依赖Blazor的
<input type="file" accept="image/*;capture=camera">,该逻辑在Hybrid模式下受系统限制,无法稳定唤起原生相机 - 若需自定义相机界面,可通过
Intent调用Android原生相机组件,在MainActivity的OnActivityResult中处理拍照结果
内容的提问来源于stack exchange,提问作者Johnny
相关产品推荐
相关产品推荐

