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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 11:53:13