首页 > 解决方案 > 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>

标签: xamarinxamarin.formsxamarin.android

解决方案


我有一个 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" />

推荐阅读