Prashant Sharma
Prashant Sharma

Reputation: 91

Access to the path is denied Xamarin forms

I am trying to copy my db file to internal storage root/document. My codes are working good till Android 9 but after it i am getting the error "System.UnauthorizedAccessException: Access to the path "/storage/emulated/0/Documents/FruitsApp/Backup/Fruits.db_2021-06-28 12:20:20" is denied" I have try lots of way to copy all are working before Android 9 but after it i am getting above error. I am sharing my all codes. Thanks in advance.

----copy code

 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);
      

I have try 3 ways to copy file from source to another all ways are working till android 9 but not working after android 9.

--Android Manifest file

 <?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>

Upvotes: 1

Views: 2943

Answers (1)

ShellShocker08
ShellShocker08

Reputation: 51

I have a SQLite database saved in the internal storage of my cellphone, in a folder created folder named SQLite. I had troubles with the permissions and the path. Here's how I solved it:

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);
}

Before I called my LocalContext I check if you have writing permissions:

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;
    }

For the permissions I use 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;
        }
    }

And in the Android Manifest I have these two:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Upvotes: 1

Related Questions