xamarin - Xamarin 表单拒绝访问路径
问题描述
我正在尝试将我的 db 文件复制到内部存储根/文档。我的代码在 Android 9 之前运行良好,但之后我收到错误“ System.UnauthorizedAccessException:访问路径”/storage/emulated/0/Documents/FruitsApp/Backup/Fruits.db_2021-06-28 12:20: 20" 被拒绝"我尝试了很多方法来复制所有在 Android 9 之前都可以正常工作,但在它之后我遇到了错误。我正在分享我的所有代码。提前致谢。
----复制代码
Java.IO.File mediaStorageDir = new Java.IO.File(Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments) + path);
if (!mediaStorageDir.Exists())
{
var tt = mediaStorageDir.Mkdirs();
if (mediaStorageDir.Mkdirs() == false)
{
var fail = "failed to create";
}
}
var directoryPath = mediaStorageDir.AbsolutePath;
////////--this way to create folder is working till andorid 9
//var PathExists = Directory.Exists(directoryPath);
//if (PathExists ==false)
//{
// Directory.CreateDirectory(directoryPath);
//}
var dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Fruits.db");
FileInfo file = new FileInfo(dbPath);
var dbName = file.Name;
var fullFileName = string.Concat("/", dbName + "_", Global.CurrentDateTime());
var newpath = string.Format("{0}{1}", directoryPath, fullFileName);
//////--- First way copy file from source to destination is working tille android 9
//using (FileStream sourceStream = System.IO.File.Open(dbPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
//using (FileStream destinationStream = System.IO.File.Create(newpath))
//{
// sourceStream.CopyToAsync(destinationStream);
//}
//////--- 2nd way copy file from source to destination is working tille android 9
byte[] dbFile = System.IO.File.ReadAllBytes(dbPath);
System.IO.File.WriteAllBytes(newpath, dbFile);
//////--- 3rd way copy file from source to destination is working tille android 9
//file.CopyTo(newpath);
我尝试了 3 种方法将文件从源复制到另一个所有方法都可以工作到 android 9,但在 android 9 之后不能工作。
--Android 清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1"
android:versionName="1.0" package="com.NewWave.FruitApp" android:installLocation="auto">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="30" />
<application android:requestLegacyExternalStorage="true" android:label="FruitApp"
android:theme="@style/MainTheme"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<!--<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />-->
</manifest>
解决方案
我有一个 SQLite 数据库保存在我手机的内部存储器中,在一个名为 SQLite 的文件夹中创建的文件夹中。我在权限和路径方面遇到了麻烦。这是我解决它的方法:
private readonly SQLiteAsyncConnection _conn;
public LocalContext()
{
// Create directory for SQLite
Directory.CreateDirectory(Path.Combine("/storage/emulated/0/","SQLite"));
string dbPath = Path.Combine(
"/storage/emulated/0/SQLite",
"ventaMovil.db");
_conn = new SQLiteAsyncConnection(dbPath);
}
在调用 LocalContext 之前,我会检查您是否具有写入权限:
private async Task<bool> CheckPermissions()
{
var status = await _permissionService.CheckAndRequestPermissionAsync(new Permissions.StorageWrite());
if (status != PermissionStatus.Granted)
{
await App.Current.MainPage.DisplayAlert("Error", "You do not have writing permissions", "Okay");
return false;
}
return true;
}
对于我使用 Xamarin Essentials 的权限:
public class PermissionService : IPermissionService
{
public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission) where T : Permissions.BasePermission
{
var status = await permission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await permission.RequestAsync();
}
return status;
}
}
在 Android Manifest 我有这两个:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
推荐阅读
- javascript - 使用带有钩子的 React.memo 来控制输入
- ios - CoreData:将数据保存到上下文
- react-redux - 在 React 和 Redux 中创建错误时出现网络错误
- java - 如何将函数 x 中的值用于函数 y 中的构造函数
- php - Codeigniter select_sum 生成错误的查询
- angular - 实时服务器响应 Angular 应用程序返回什么?
- flask - 多对多关系 - 如何查询所有孩子
- laravel - 如何使用 laradock 备份数据库 mongodb
- node.js - Angular 5 自定义管道
- reactjs - 如何将 isConnect 状态传递给其他类