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

Xamarin.Android应用适配SDK30存储权限被拒及Android11崩溃求助

Xamarin.Android SDK30适配+上架+Android11兼容解决方案

第一步:清理AndroidManifest配置

直接修改你的清单文件如下,删除不必要的权限和配置:

<!-- 移除以下4行配置 -->
<!-- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> -->
<!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> -->
<!-- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> -->
<!-- <protected-broadcast android:name="android.intent.action.MEDIA_MOUNTED" /> -->

<!-- 保留业务需要的其他权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />

<application android:allowBackup="true" android:label="AppName" android:icon="@mipmap/logoIconWhite" android:requestLegacyExternalStorage="true">
    <!-- 补全FileProvider配置,${applicationId}会自动替换为你的应用包名 -->
    <provider android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

在Resources/xml文件夹下新建file_paths.xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="AppName" path="AppName" />
</paths>

第二步:清理冗余业务代码

你原有代码中大量对公共存储根目录的操作是Android11崩溃的直接原因,且这些逻辑完全冗余,你实际存储PDF用的是应用专属目录,不需要读写公共存储。修改后的PDFDrawer方法如下:

private async void PDFDrawer(int pos)
{
    UI ui = new UI(this);
    ui.ShowProgressDialog("", "Laden");
    Console.WriteLine(invoices[pos].Obj["InvoiceID"].ToString());

    // 原有的PDF获取逻辑保留
    JsonValue json = await getPDFTask(invoices[pos].Obj["InvoiceID"].ToString());
    var PDFResults = json["InvoicePDFResponse_InvoicePDF"];
    var pdf = (string)PDFResults[0]["PDFString"];
    byte[] pdfAsBytes = Convert.FromBase64String(pdf);

    // GetExternalFilesDir为应用专属目录,无需申请任何存储权限即可读写,符合谷歌存储政策
    var pdfDir = Android.App.Application.Context.GetExternalFilesDir("AppName");
    if (!pdfDir.Exists())
    {
        pdfDir.Mkdirs();
    }
    var externalPath = Path.Combine(pdfDir.AbsolutePath, "invoice.pdf");
    File.WriteAllBytes(externalPath, pdfAsBytes);

    // 打开PDF
    OpenFile(externalPath);

    ui.HideProgressDialog();
}

第三步:适配文件打开逻辑

你需要通过FileProvider给第三方PDF阅读器授予文件访问权限,修改OpenFile方法如下:

private void OpenFile(string filePath)
{
    var file = new Java.IO.File(filePath);
    var uri = FileProvider.GetUriForFile(this, PackageName + ".fileprovider", file);
    
    var intent = new Intent(Intent.ActionView);
    intent.SetDataAndType(uri, "application/pdf");
    intent.AddFlags(ActivityFlags.GrantReadUriPermission);
    intent.AddFlags(ActivityFlags.NewTask);
    
    StartActivity(intent);
}

适配说明

  • 应用专属目录仅你的应用可访问,无需申请任何存储权限,完全符合谷歌存储政策,不会触发权限相关审核驳回
  • 移除了所有公共存储读写操作,Android11及以上系统不会再出现权限异常崩溃
  • 无敏感权限申请,审核通过率高

内容的提问来源于stack exchange,提问作者Justin van Brecht

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 09:09:03