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

Xamarin Forms写入JSON文件遇权限拒绝问题求助

解决Android中写入JSON文件时的System.UnauthorizedAccessException问题

1. 动态申请存储权限(Android 6.0+)

WRITE_EXTERNAL_STORAGE属于危险权限,仅在AndroidManifest.xml中声明不够,必须在运行时向用户申请。示例代码:

private const int RequestStorageId = 100;

// 在执行写入操作前调用,检查并申请权限
private void CheckStoragePermission()
{
    if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) != Permission.Granted)
    {
        ActivityCompat.RequestPermissions(this, new[] { Manifest.Permission.WriteExternalStorage }, RequestStorageId);
    }
    else
    {
        // 权限已授予,执行写入逻辑
        StoreGameProgress();
    }
}

// 处理权限申请结果
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == RequestStorageId)
    {
        if (grantResults.Length > 0 && grantResults[0] == Permission.Granted)
        {
            StoreGameProgress();
        }
        else
        {
            Toast.MakeText(this, "需要存储权限才能保存游戏进度", ToastLength.Short).Show();
        }
    }
}

2. 使用合法的存储路径

避免直接使用根目录或未授权的自定义路径,优先选择以下安全路径:

  • 应用私有外部存储:Android 10+无需动态权限,文件随应用卸载自动删除
    // 获取应用私有外部存储目录
    string privatePath = Path.Combine(GetExternalFilesDir(null).AbsolutePath, "game_progress.json");
    
  • 公共存储目录(如Documents、Downloads):需要动态权限(Android 6.0+)
    string publicPath = Path.Combine(Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDocuments).AbsolutePath, "game_progress.json");
    

3. 适配Android 10+分区存储

Android 10(API 29)及以上默认启用分区存储,禁止直接访问外部存储的非私有目录:

  • 若使用应用私有外部存储,无需额外配置
  • 若必须访问公共目录,在AndroidManifest.xml的<application>标签中添加临时兼容配置:
    android:requestLegacyExternalStorage="true"
    
    注:Android 11+建议改用MediaStore API访问公共文件。

4. 修正文件写入逻辑

确保写入时路径正确、无文件占用问题,示例代码:

private void StoreGameProgress()
{
    // 序列化游戏状态为JSON字符串
    string jsonContent = JsonConvert.SerializeObject(yourGameStateModel);
    string filePath = Path.Combine(GetExternalFilesDir(null).AbsolutePath, "game_progress.json");
    
    try
    {
        File.WriteAllText(filePath, jsonContent);
        Toast.MakeText(this, "进度保存成功", ToastLength.Short).Show();
    }
    catch (Exception ex)
    {
        Toast.MakeText(this, $"保存失败:{ex.Message}", ToastLength.Long).Show();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 01:25:30