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?