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

MAUI Android应用启动时申请存储权限的代码实现位置咨询

MAUI Android存储权限申请实现指南

一、AndroidManifest.xml权限配置

根据Android版本差异,添加对应权限:

  • Android 10(API 29)及以下:添加读写外部存储权限
  • Android 11(API 30)及以上:如需访问公共存储目录,额外添加管理外部存储权限

在Platforms/Android/AndroidManifest.xml中添加以下代码:

<!-- Android 10及以下所需权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<!-- Android 11+ 访问公共存储所需权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

<!-- 针对Android 10的分区存储适配 -->
<application android:requestLegacyExternalStorage="true" ...>

二、存储权限申请代码实现

参考你提供的位置权限逻辑,我们可以复用类似结构实现存储权限的检查与申请,具体步骤如下:

1. 添加存储权限检查方法

在MainPage.xaml.cs中,与CheckAndRequestLocationPermission方法同级,新增存储权限处理方法:

public async Task<PermissionStatus> CheckAndRequestStoragePermission()
{
    PermissionStatus status;
    // 适配Android 13+的细分存储权限
    if (DeviceInfo.Version.Major >= 13)
    {
        status = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
        if (status != PermissionStatus.Granted)
        {
            status = await Permissions.RequestAsync<Permissions.StorageRead>();
        }
        // 如需写入操作,额外申请写入权限
        var writeStatus = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
        if (writeStatus != PermissionStatus.Granted)
        {
            writeStatus = await Permissions.RequestAsync<Permissions.StorageWrite>();
        }
    }
    else
    {
        // Android 12及以下使用统一存储权限
        status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
        if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
        {
            return status;
        }
        if (Permissions.ShouldShowRationale<Permissions.StorageWrite>())
        {
            await DisplayAlert("权限说明", "需要访问公共存储读取和修改Excel文件", "知道了");
        }
        status = await Permissions.RequestAsync<Permissions.StorageWrite>();
    }
    return status;
}

2. 在应用启动时触发权限申请

推荐在页面生命周期方法OnAppearing中调用权限申请(避免在构造函数中阻塞UI),修改MainPage类:

protected override async void OnAppearing()
{
    base.OnAppearing();
    // 页面加载时自动申请存储权限
    var storageStatus = await CheckAndRequestStoragePermission();
    if (storageStatus != PermissionStatus.Granted)
    {
        await DisplayAlert("权限不足", "无法访问公共存储,请授予权限后重试", "确定");
    }
}

3. 确保文件操作前权限已生效

修改OnCounterClicked方法,先验证存储权限再执行Excel操作:

private async void OnCounterClicked(object sender, EventArgs e)
{
    // 先检查存储权限状态
    var storageStatus = await CheckAndRequestStoragePermission();
    if (storageStatus != PermissionStatus.Granted)
    {
        await DisplayAlert("权限不足", "无法访问公共存储", "确定");
        return;
    }

    // 原Excel操作逻辑保留,添加异常捕获
    ExcelEngine excelEngine = new ExcelEngine();
    Syncfusion.XlsIO.IApplication application = excelEngine.Excel;

    string rootPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim).AbsolutePath;
    string backingFile = Path.Combine(rootPath, "Proof.xlsx");
    
    try
    {
        FileStream inputStream = new FileStream(backingFile, FileMode.Open, FileAccess.Read);
        IWorkbook workbook = application.Workbooks.Open(inputStream, ExcelOpenType.Automatic);
        IWorksheet worksheet = workbook.Worksheets[0];
        worksheet.Range["A5"].Text = "Brilliant";

        string savePath = Android.App.Application.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryDocuments).ToString();
        string saveFile = Path.Combine(savePath, "Proof.xlsx");

        FileStream stream = new FileStream(saveFile, FileMode.Create, FileAccess.ReadWrite);
        workbook.SaveAs(stream);
        workbook.Close();
        await DisplayAlert("操作成功", "Excel文件已修改保存", "确定");
    }
    catch (Exception ex)
    {
        await DisplayAlert("错误", $"文件操作失败:{ex.Message}", "确定");
    }
    finally
    {
        excelEngine.Dispose();
    }
}

三、完整修改后的MainPage.xaml.cs代码

using Microsoft.Maui.Controls.PlatformConfiguration;
using Syncfusion.XlsIO;
using System.Reflection;
using Microsoft.Maui.Storage;
using Microsoft.Maui.Devices;

namespace MauiApp3
{
    public partial class MainPage : ContentPage
    {
        int count = 0;

        public MainPage()
        {
            InitializeComponent();
        }

        public async Task<PermissionStatus> CheckAndRequestLocationPermission()
        {
            PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();

            if (status == PermissionStatus.Granted)
                return status;

            if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
            {
                return status;
            }

            if (Permissions.ShouldShowRationale<Permissions.LocationWhenInUse>())
            {
                await DisplayAlert("权限说明", "需要位置权限以提供相关服务", "知道了");
            }

            status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

            return status;
        }

        public async Task<PermissionStatus> CheckAndRequestStoragePermission()
        {
            PermissionStatus status;
            if (DeviceInfo.Version.Major >= 13)
            {
                status = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
                if (status != PermissionStatus.Granted)
                {
                    status = await Permissions.RequestAsync<Permissions.StorageRead>();
                }
                var writeStatus = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
                if (writeStatus != PermissionStatus.Granted)
                {
                    writeStatus = await Permissions.RequestAsync<Permissions.StorageWrite>();
                }
            }
            else
            {
                status = await Permissions.CheckStatusAsync<Permissions.StorageWrite>();
                if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
                {
                    return status;
                }
                if (Permissions.ShouldShowRationale<Permissions.StorageWrite>())
                {
                    await DisplayAlert("权限说明", "需要访问公共存储读取和修改Excel文件", "知道了");
                }
                status = await Permissions.RequestAsync<Permissions.StorageWrite>();
            }
            return status;
        }

        protected override async void OnAppearing()
        {
            base.OnAppearing();
            var storageStatus = await CheckAndRequestStoragePermission();
            if (storageStatus != PermissionStatus.Granted)
            {
                await DisplayAlert("权限不足", "无法访问公共存储,请授予权限后重试", "确定");
            }
        }

        private async void OnCounterClicked(object sender, EventArgs e)
        {
            var storageStatus = await CheckAndRequestStoragePermission();
            if (storageStatus != PermissionStatus.Granted)
            {
                await DisplayAlert("权限不足", "无法访问公共存储", "确定");
                return;
            }

            ExcelEngine excelEngine = new ExcelEngine();
            Syncfusion.XlsIO.IApplication application = excelEngine.Excel;

            string rootPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim).AbsolutePath;
            string backingFile = Path.Combine(rootPath, "Proof.xlsx");
            
            try
            {
                FileStream inputStream = new FileStream(backingFile, FileMode.Open, FileAccess.Read);
                IWorkbook workbook = application.Workbooks.Open(inputStream, ExcelOpenType.Automatic);
                IWorksheet worksheet = workbook.Worksheets[0];
                worksheet.Range["A5"].Text = "Brilliant";

                string savePath = Android.App.Application.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryDocuments).ToString();
                string saveFile = Path.Combine(savePath, "Proof.xlsx");

                FileStream stream = new FileStream(saveFile, FileMode.Create, FileAccess.ReadWrite);
                workbook.SaveAs(stream);
                workbook.Close();
                await DisplayAlert("操作成功", "Excel文件已修改保存", "确定");
            }
            catch (Exception ex)
            {
                await DisplayAlert("错误", $"文件操作失败:{ex.Message}", "确定");
            }
            finally
            {
                excelEngine.Dispose();
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:35:53