.Net Android (Maui) Writing external storage doesn't work until I restart the application in below 13 version

67 Views Asked by At

I am requesting runtime permissions on button click :

ActivityCompat.RequestPermissions(Activity,
new String[] {  Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage },
100);

The callback for setting the permissions:

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{

base.OnRequestPermissionsResult(requestCode, permissions, grantResults);

switch (requestCode)
{
    case 100:
        {
            if (grantResults[0] == Android.Content.PM.Permission.Granted || Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu)
            {
                SendNavigationData(NavigatedFrom.StoragePermissionCard);
            }
            
        }
        break;

    default:
        Console.WriteLine("Unhandled option : " + requestCode);
        break;
}
}

I should be able to access storage on immediate allowing session

2

There are 2 best solutions below

4
Jessie Zhang -MSFT On

Update:

I am facing challenges in Accessing the Runtime Allowed Storage Permissions in .Net Android (Maui)

In Maui, you can use Permissions to achieve this.

You can check permissions by code:

 PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();

and requesting permissions by code:

PermissionStatus status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

For more information, please check: Extending permissions.

And there is an official sample, you can check it here: Sample.

I achieved this function on my side, you can refer to the following code:

MainActivity.cs

public class MainActivity : Activity
   {
       public  string TAG
       {
           get
           {
               return "MainActivity";
           }
       }

       Button button;

       static string[] PERMISSIONS_STORAGE = {
           Manifest.Permission.ReadExternalStorage,
           Manifest.Permission.WriteExternalStorage
       };

       static readonly int REQUEST_STORAGE = 1;

       protected override void OnCreate(Bundle? savedInstanceState)
       {
           base.OnCreate(savedInstanceState);

           // Set our view from the "main" layout resource
           SetContentView(Resource.Layout.activity_main);

           button = FindViewById<Button>(Resource.Id.button1);
           button.Click += Button_Click;
       }

       private void Button_Click(object? sender, EventArgs e)
       {
           DoSomething();
       }

       public void DoSomething()
       {

           // Verify that all required ExternalStorage permissions have been granted.
           if (ActivityCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) != (int)Permission.Granted
               || ActivityCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) != (int)Permission.Granted)
           {
               // ExternalStorage permissions have not been granted.
               Log.Info(TAG, " permissions has NOT been granted. Requesting permissions.");
               RequestExternalStoragePermissions();
           }
           else
           {
               // ExternalStorage permissions have been granted.
               Log.Info(TAG, "ExternalStorage permissions have already been granted. ");

               // do something you want

               DoSometingYouWant();
           }
       }

       private void RequestExternalStoragePermissions()
       {
           if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.ReadExternalStorage)
               || ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.WriteExternalStorage))
           {

               // Provide an additional rationale to the user if the permission was not granted
               // and the user would benefit from additional context for the use of the permission.
               // For example, if the request has been denied previously.
               Log.Info(TAG, "Displaying ExternalStorage permission rationale to provide additional context.");

               // Display a SnackBar with an explanation and a button to trigger the request.

           }
           else
           {
               //  permissions have not been granted yet. Request them directly.
               ActivityCompat.RequestPermissions(this, PERMISSIONS_STORAGE, REQUEST_STORAGE);
           }
       }


       public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
       {

           if (requestCode == REQUEST_STORAGE)
           {
               Log.Info(TAG, "Received response for contact permissions request.");

               // We have requested multiple permissions for storage, so all of them need to be
               // checked.
               if (PermissionUtil.VerifyPermissions(grantResults))
               {
                   // All required permissions have been granted

                   // add your code here
                   DoSometingYouWant();
               }
               else
               {
                   Log.Info(TAG, "permissions were NOT granted.");
               }

           }
           else
           {
               base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
           }
       }

       void DoSometingYouWant() {
       
         
       }

   }

PermissionUtil.cs

public abstract class PermissionUtil
{
    public static bool VerifyPermissions(Permission[] grantResults)
    {
        // At least one result must be checked.
        if (grantResults.Length < 1)
            return false;

        // Verify that each required permission has been granted, otherwise return false.
        foreach (Permission result in grantResults)
        {
            if (result != Permission.Granted)
            {
                return false;
            }
        }
        return true;
    }
}

You also need to add the following permissions to AndroidManifest.xml.

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

For more information, you can check the official document : External storage and Permissions In Xamarin.Android.

And there is an official sample here: RuntimePermissions.

0
user2153142 On

You don't specify what version of Android you are building. Since Android 11, you can't get permission to write to external storage, unless Google Play approves (eg. for a file explorer app) so you need a different approach.

The following links explain using a different approach for reading/writing data.

https://medium.com/swlh/sample-for-android-storage-access-framework-aka-scoped-storage-for-basic-use-cases-3ee4fee404fc

https://www.zoftino.com/how-to-create-browse-files-option-in-android

https://mateuszteteruk.pl/how-to-use-android-storage-access-framework-with-example

https://thedroidlady.com/2020-08-24-android-scoped-storage-demystified