Xamarin Forms无法访问相机:Android端拍照代码问题求助
解决Xamarin.Android拍照代码无法访问相机的问题
嘿,看了你的代码,大概率是权限或者Android版本适配的问题,我给你拆解几个关键修复点,一步步来:
1. 先搞定相机权限——Android 6.0+必须动态申请
从Android 6.0(API 23)开始,光在Manifest里加权限没用,得在运行时主动请求用户授权:
首先,打开AndroidManifest.xml,把这些静态权限加上:
<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" />
然后,别直接调用TakePhoto(),先加个权限检查的方法,确保用户授权了再启动相机:
private async Task CheckAndRequestCameraPermission() { var permissionStatus = await Permissions.CheckStatusAsync<Permissions.Camera>(); if (permissionStatus != PermissionStatus.Granted) { permissionStatus = await Permissions.RequestAsync<Permissions.Camera>(); } if (permissionStatus == PermissionStatus.Granted) { TakePhoto(); // 权限通过,再调用拍照方法 } else { Toast.MakeText(MainActivity.Instance, "没有相机权限没法拍照哦", ToastLength.Short).Show(); } }
2. Android 7.0+要适配FileProvider,别直接用Uri.FromFile()
从Android 7.0开始,直接暴露文件Uri会触发FileUriExposedException,必须用FileProvider来安全生成Uri:
第一步:在Manifest里注册FileProvider
打开AndroidManifest.xml,在<application>标签里加这段:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
第二步:创建文件路径配置文件
在你的项目Resources目录下新建一个xml文件夹,然后创建file_paths.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 这里对应你存放照片的目录,比如你代码里的AppCamera._dir是外部存储的Pictures文件夹 --> <external-files-path name="camera_photos" path="Pictures" /> </paths>
第三步:修改TakePhoto()里的Uri生成逻辑
把原来的Uri.FromFile(AppCamera._file)替换成FileProvider的写法,还要加上权限授予,另外别忘了检查存储目录是否存在:
public void TakePhoto() { Context context = MainActivity.Instance; MainActivity activity = (MainActivity)context; // 先检查存储目录是否存在,不存在就创建! if (!AppCamera._dir.Exists()) { AppCamera._dir.Mkdirs(); } Intent intent = new Intent(MediaStore.ActionImageCapture); AppCamera._file = new Java.IO.File(AppCamera._dir, String.Format("Photo_{0}.jpg", DateTime.Now.ToString("ddMMyyHHmmss"))); // 替换Uri生成方式 var photoUri = FileProvider.GetUriForFile(context, context.PackageName + ".fileprovider", AppCamera._file); intent.PutExtra(MediaStore.ExtraOutput, photoUri); // 给相机APP授予读写Uri的权限 intent.AddFlags(ActivityFlags.GrantReadUriPermission); intent.AddFlags(ActivityFlags.GrantWriteUriPermission); activity.StartActivityForResult(intent, 1); }
3. 可选:替换弃用的StartActivityForResult
如果你的Xamarin版本比较新,StartActivityForResult已经被标记为弃用了,建议改用ActivityResultContracts.TakePicture,不过这个是优化项,先把前面的问题解决了再考虑也没问题。
按照上面的步骤改完,相机应该就能正常访问了,要是还有问题可以再补充细节~
内容的提问来源于stack exchange,提问作者Ronjon
相关产品推荐
相关产品推荐

