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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:31:53