Xamarin Forms(C#)存储权限申请异常:未弹出权限请求弹窗
存储权限请求不弹出的问题排查与解决
我需要申请存储权限来读写JSON数据文件,权限被拒绝时关闭应用,但目前应用没有弹出权限请求弹窗,以下是我的主应用代码:
using System; using Xamarin.Forms; using Xamarin.Forms.Xaml; using TravelPack.Views; using System.Diagnostics; using System.IO; using Xamarin.Essentials; namespace TravelPack { public partial class App : Application { public App() { InitializeComponent(); } protected override void OnStart() { CheckStoragePermission(); //TravelPack.OOP.Lists.InitializeLists(); } protected override void OnSleep() { } protected override void OnResume() { } private async void CheckStoragePermission() { var status = await Permissions.CheckStatusAsync<Permissions.StorageRead>(); if (status != PermissionStatus.Granted) { status = await Permissions.RequestAsync<Permissions.StorageRead>(); if (status != PermissionStatus.Granted) { CloseApp(); } } } private void CloseApp() { System.Diagnostics.Process.GetCurrentProcess().Kill(); } } }
问题原因分析
- 平台权限声明缺失:Android和iOS都需要在配置文件中提前声明权限,否则系统不会触发权限请求弹窗。
- 权限类型不完整:仅申请
StorageRead权限不足以覆盖读写JSON文件的需求,通常需要同时申请StorageWrite。 - 异步方法调用问题:
CheckStoragePermission是async void类型,在OnStart中直接调用会导致异步操作未被正确等待,可能影响权限请求流程。 - 平台版本限制:Android 13+对存储权限模型做了调整,传统存储权限已被废弃,需适配新的权限规则。
解决方案
1. 补充平台权限声明
Android(AndroidManifest.xml)
添加必要的存储权限声明:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 若目标Android 13+,操作媒体文件需添加以下权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
iOS(Info.plist)
添加权限使用描述,否则iOS会直接拒绝权限请求:
<key>NSDocumentsFolderUsageDescription</key> <string>需要访问文档文件夹存储JSON数据</string> <!-- 若涉及媒体文件访问,需添加对应描述 --> <key>NSPhotoLibraryUsageDescription</key> <string>需要访问相册存储数据</string>
2. 修正权限请求逻辑
将异步方法改为async Task并确保调用时等待,同时申请读写权限:
protected override async void OnStart() { await CheckStoragePermission(); //TravelPack.OOP.Lists.InitializeLists(); } private async Task CheckStoragePermission() { // 同时检查读写权限状态 var readStatus = await Permissions.CheckStatusAsync<Permissions.StorageRead>(); var writeStatus = await Permissions.CheckStatusAsync<Permissions.StorageWrite>(); if (readStatus != PermissionStatus.Granted || writeStatus != PermissionStatus.Granted) { // 分别请求读写权限 readStatus = await Permissions.RequestAsync<Permissions.StorageRead>(); writeStatus = await Permissions.RequestAsync<Permissions.StorageWrite>(); // 任一权限未授予则关闭应用 if (readStatus != PermissionStatus.Granted || writeStatus != PermissionStatus.Granted) { CloseApp(); } } }
3. 适配Android 13+存储规则
如果应用目标是Android 13(API 33)及以上:
- 若仅存储应用私有数据,可直接使用应用私有目录(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)),无需申请权限。 - 若需访问公共存储的非媒体文件,需申请
MANAGE_EXTERNAL_STORAGE权限(需通过谷歌Play审核);若操作媒体文件,使用新的READ_MEDIA_*权限。
4. 优化应用关闭方式
避免使用强制终止进程的方式,改用Xamarin.Forms官方提供的退出方法:
private void CloseApp() { Application.Current.Quit(); }
内容的提问来源于stack exchange,提问作者Gael Pinto
相关产品推荐
相关产品推荐

