Search code examples
androidxamarin.formspermissionsandroid-external-storage

Unable to read external storage in Xamarin.Forms for Android


In the Xamarin.Forms application we are developing, called "myApp", targeting Android devices only, we need to be able to read from (and possibly write to) the text file

storage/emulated/0/Android/data/com.myApp.configuration/myAppStuff.txt

which in the Windows 10 development platform appears as

This PC\DEVICE TYPE\Internal shared storage\Android\data\com.myApp.configuration\

In the AndroidManifest.xml file for the project, we have included

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" ... >
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>
</manifest>

This is confirmed in Visual Studio 2022 by navigating to

Project > myApp.Android Properties > Android Manifest > Required permissions:

and observing the required permissions are asserted.

When the application is first started in the debug mode, in MainActivity.cs

AndroidX.Core.App.ActivityCompat.CheckSelfPermission(this, Android.Manifest.Permission.ReadExternalStorage)

returns "false", so we invoke

AndroidX.Core.App.ActivityCompat.RequestPermissions(this, new string[] { Android.Manifest.Permission.ReadExternalStorage, Android.Manifest.Permission.WriteExternalStorage, Android.Manifest.Permission.ManageExternalStorage }, 0)

Android shows a (non-modal) dialog

dialog

for which we select "ALLOW".

Later, the code

File.Exists("/storage/emulated/0/Android/data/com.myApp.configuration/myAppStuff.txt")

returns "true"

but the code

mystreamreader = new StreamReader("/storage/emulated/0/Android/data/com.myApp.configuration/myAppStuff.txt");

throws the exception with Message value of

"Access to the path \"/storage/emulated/0/Android/data/com.myApp.configuration/myAppStuff.txt\" is denied."

A later check shows that the code

AndroidX.Core.App.ActivityCompat.CheckSelfPermission(this, Android.Manifest.Permission.ManageExternalStorage)

returns the value "false".

Why?


Solution

  • I can't reproduce your problem. But you said:

    we need to be able to read from (and possibly write to) the text file

    So I created a sample to read and write the text file:

    In my AndroidManifest.xml:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0"
                  package="com.companyname.app21">
        <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
        <application android:label="App21.Android" android:theme="@style/MainTheme"></application>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    </manifest>
    

    Please make sure the package's value in your AndroidManifest.xml file is com.myApp.configuration.

    And the code about create, read and write the file:

    FileStream filestream = new FileStream("/storage/emulated/0/Android/data/com.companyname.app21/test.txt",
                                                         FileMode.OpenOrCreate,
                                                         FileAccess.ReadWrite,
                                                         FileShare.ReadWrite); 
    // create the text file     
    File.WriteAllText("/storage/emulated/0/Android/data/com.companyname.app21/test.txt", "this is content");
    // write the text file
    var content = File.ReadAllText("/storage/emulated/0/Android/data/com.companyname.app21/test.txt");
    //read the text file