.NET Android App can read textfile in Documents only if created by itself

70 Views Asked by At

I'm writing an Android app in .NET using Avalonia. I'm attempting to read a textfile from the Documents folder, but am hitting an odd behavior: I can read the file only if it was created by the app itself, and in no other case. Below is an example with comments to explain:

private async void test_command()
{
    // Use Xamarin.Essentials to get READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE
    // The permissions are also listed in the manifest.
    // This succeeds, shows the prompt, & says "granted"
    var hasRead = await Permissions.RequestAsync<Permissions.StorageRead>();
    var hasWrite = await Permissions.RequestAsync<Permissions.StorageWrite>();
    if (hasWrite != PermissionStatus.Granted || hasRead != PermissionStatus.Granted)
    {
        show_notification_warning("Storage Permission denied");
        return;
    }

    var dirname = "/storage/emulated/0/Documents/";
    var defaultFilename = "test.txt";
    var content = "This is some sample content";

    // Ask for a filename & write some text
    // (the dialog is handled by HanumanInstitute.MvvmDialogs).
    // This works.
    var promptVm = _dialogService.CreateViewModel<TextPromptViewModel>();
    promptVm.Title = "Enter filename to WRITE";
    promptVm.Text = defaultFilename;
    var success = await _dialogService.ShowDialogAsync<TextPromptWindow>(this, promptVm).ConfigureAwait(true);
    if (success.Value)
    {
        var writeFilename = dirname + promptVm.Text;
        using (var writer = System.IO.File.CreateText(writeFilename))
        {
            await writer.WriteLineAsync(content);
        }
    }

    // Now ask for another filename to read.
    // If I read back the file I just created, it works.
    // However, if I enter the name of a file that I copied into the device
    // over USB, or created with a text editor app, it throws 
    // System.UnauthorizedAccessException: Access to the path '/storage/emulated/0/Documents/test2.txt' is denied.
    promptVm = _dialogService.CreateViewModel<TextPromptViewModel>();
    promptVm.Title = "Enter filename to READ";
    promptVm.Text = defaultFilename;
    success = await _dialogService.ShowDialogAsync<TextPromptWindow>(this, promptVm).ConfigureAwait(true);
    if (success.Value)
    {
        var readFilename = dirname + promptVm.Text;
        using (var reader = System.IO.File.OpenText(readFilename))
        {
            var readBack = await reader.ReadToEndAsync();
        }
    }
}

At first it looks like a file permissions issue, but I've checked both the permissions & the owner and they're identical. i.e. if I have Documents/test1.txt and Documents/test2.txt, where one was created by the app per above (and can be read) and the other was copied onto the device or created by a texteditor app (and throws), both show the same permissions and the same owner.

Why won't Android let me open a textfile that I've copied into the Document folder or created with another app?

0

There are 0 best solutions below