Xamarin从SQLite数据库导出PDF遇权限拒绝异常求助
你遇到的错误是因为直接尝试写入系统根目录,而Android/iOS都严格限制了对根目录的直接访问,必须使用系统允许的存储路径。以下是两种可行的解决方案:
方案一:使用应用私有存储目录(无需额外权限)
这个路径只有你的应用能访问,适合不需要用户在外部文件管理器查看的场景,代码实现简单:
var item = e.CurrentSelection[0] as SamplesData; byte[] pdfBytes = (byte[])item.PDF; string fileName = "kms.pdf"; // 获取应用私有存储目录路径 string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), fileName); // 写入文件(using语句会自动释放资源,比手动Close更安全) using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write)) { fs.Write(pdfBytes, 0, pdfBytes.Length); } // 打开文件 File.OpenRead(filePath);
方案二:导出到公共存储目录(让用户可在文件管理器查看)
如果需要把PDF导出到用户能直接访问的位置(比如下载文件夹),需要处理不同平台的权限和路径:
Android端实现
- 先在
AndroidManifest.xml中添加权限:
<!-- Android 12及以下需要的读写权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- Android 13+ 针对文档的读取权限 --> <uses-permission android:name="android.permission.READ_MEDIA_DOCUMENTS" android:minSdkVersion="33" />
- 动态申请权限并写入文件:
var item = e.CurrentSelection[0] as SamplesData; byte[] pdfBytes = (byte[])item.PDF; string fileName = "kms.pdf"; // 获取公共下载目录路径 string downloadsPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath; string filePath = Path.Combine(downloadsPath, fileName); // Android 6.0+ 需要动态申请权限 if (ContextCompat.CheckSelfPermission(Android.App.Application.Context, Manifest.Permission.WriteExternalStorage) != Permission.Granted) { ActivityCompat.RequestPermissions((Android.App.Activity)Xamarin.Essentials.Platform.CurrentActivity, new string[] { Manifest.Permission.WriteExternalStorage }, 1); // 权限申请结果会在OnRequestPermissionsResult回调中返回,拿到权限后再执行写入操作 return; } // 写入文件 using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write)) { fs.Write(pdfBytes, 0, pdfBytes.Length); } // 通知系统媒体扫描器,让文件立刻在文件管理器中显示 MediaScannerConnection.ScanFile(Android.App.Application.Context, new string[] { filePath }, null, null);
iOS端实现
iOS可以写入应用的Documents目录,若要让用户在系统文件应用中看到,还需配置Info.plist:
var item = e.CurrentSelection[0] as SamplesData; byte[] pdfBytes = (byte[])item.PDF; string fileName = "kms.pdf"; // 获取应用Documents目录路径 string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string filePath = Path.Combine(documentsPath, fileName); // 写入文件 using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write)) { fs.Write(pdfBytes, 0, pdfBytes.Length); }
然后在Info.plist中添加以下配置,开启文件共享:
<key>UIFileSharingEnabled</key> <true/> <key>LSSupportsOpeningDocumentsInPlace</key> <true/>
内容的提问来源于stack exchange,提问作者mohammad esawe
相关产品推荐
相关产品推荐

