Xamarin Android无法在存储中创建文件:权限被拒问题求助
问题分析与解决方案
核心问题1:权限请求代码错误
你当前的权限请求逻辑存在明显错误:
- 在
if分支中,判断是否缺少WRITE_EXTERNAL_STORAGE权限,但实际请求的却是Camera权限,导致权限弹窗永远不会申请你需要的存储权限。 else分支中,明明已经拥有权限,却重复发起权限请求,完全冗余。
核心问题2:权限请求后立刻执行文件操作
ActivityCompat.RequestPermissions是异步操作,调用后不会立刻拿到权限,你紧接着调用eCreateFile,此时权限还未授予,必然触发权限拒绝报错。
修复步骤
1. 修正权限请求逻辑(利用已安装的Plugin.Permissions)
将点击事件中的权限请求代码替换为异步逻辑,等待权限请求结果后再执行文件操作:
_start.Click += async (sender, e) => { _stop.Enabled = !_stop.Enabled; _start.Enabled = !_start.Enabled; _text2.Text = path.ToString(); // 检查存储权限状态 var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage); if (status != PermissionStatus.Granted) { // 发起权限请求 var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage); status = results[Permission.Storage]; } // 权限授予后执行文件创建 if (status == PermissionStatus.Granted) { eCreateFile(path); } else { _text3.Text = "存储权限未授予,无法创建文件"; } };
2. 移除冗余代码
删除原来的static readonly int WRITE_EXTERNAL_STORAGE = 0;以及旧的ActivityCompat.RequestPermissions相关代码。
3. 可选:改用应用专属存储路径(无需权限)
如果不需要让其他应用访问这个文件,建议使用应用专属外部存储路径,无需申请存储权限,且卸载应用时文件会自动删除:
// 获取应用专属外部存储目录 string path = Path.Combine(ApplicationContext.GetExternalFilesDir(null).AbsolutePath, "esi2.txt");
4. 验证Manifest配置(当前已正确配置)
你已经添加了android:requestLegacyExternalStorage="true",对于targetSdkVersion=30(Android 10),该配置可让应用使用旧存储策略,无需适配Scoped Storage,当前配置无问题。
完整修改后的关键代码示例
public class MainActivity : AppCompatActivity { Button _start; Button _stop; TextView _text1; TextView _text2; TextView _text3; MediaRecorder Recorder; string path; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); SetContentView(Resource.Layout.activity_main); _start = FindViewById<Button>(Resource.Id.materialButton1); _stop = FindViewById<Button>(Resource.Id.materialButton2); _text1 = FindViewById<TextView>(Resource.Id.textView1); _text2 = FindViewById<TextView>(Resource.Id.textView2); _text3 = FindViewById<TextView>(Resource.Id.textView3); // 可选:应用专属路径(无需权限) // path = Path.Combine(ApplicationContext.GetExternalFilesDir(null).AbsolutePath, "esi2.txt"); // 原公共路径(需权限) path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/esi2.txt"; _start.Click += async (sender, e) => { _stop.Enabled = !_stop.Enabled; _start.Enabled = !_start.Enabled; _text2.Text = path.ToString(); var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage); if (status != PermissionStatus.Granted) { var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Storage); status = results[Permission.Storage]; } if (status == PermissionStatus.Granted) { eCreateFile(path); } else { _text3.Text = "存储权限未授予,无法创建文件"; } }; } public void eCreateFile(string FileName) { string text = "Ehsan Test"; byte[] data = System.Text.ASCIIEncoding.ASCII.GetBytes(text); try { File.WriteAllBytes(FileName, data); _text3.Text = "文件创建成功"; } catch(Exception ex) { _text3.Text = ex.Message; } } // 重写权限回调,适配插件需求 public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) { Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } }
内容的提问来源于stack exchange,提问作者eag-ehsan
相关产品推荐
相关产品推荐

