Я пытался вывести содержимое папки на SD-карту и записать ее на своем телефоне Android с помощью MAUI.
Моя цель - получить доступ к папке (а именно: SD-карта/DCIM/Test EXIF, перечислить ее содержимое и изменить/удалить метаданные файла в пакетном режиме.
Я пытался в течение нескольких дней безрезультатно, я не могу получить доступ к SD-карте и понятия не имею, как это сделать. Я попробовал простой сборщик файлов, например:
var result = await FilePicker.Default.PickAsync();
if (result != null)
{
// Do Stuff
}
Доступ к SD-карте работает, но это не то, что мне нужно: файл, по-видимому, скопирован в кеш, и я хочу, чтобы исходный файл можно было редактировать. И я хочу, чтобы обрабатывались несколько файлов, а не один за другим.
Я попробовал другой подход: с GetLogicalDrives()
string folders = "";
var xxx = System.Environment.GetLogicalDrives();
foreach (string foldnm in xxx)
folders = folders + foldnm + ";";
И в списке я нашел «/storage/emulated/0/Android/data», который, кажется, является основой того, что я ищу. Итак, я попробовал следующее:
var files = Directory.GetFiles("/storage/emulated/0/Android/data", "*");
Но у меня есть отказ в доступе: System.UnauthorizedAccessException: «Доступ к пути «/storage/emulated/0/Android/data» запрещен». Я подумал, что это правильная проблема, поэтому в Android/Resources.AndroidManifest.xml я добавил следующие строки:
<uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
Удалил/переустановил приложение и получил тот же результат, поэтому я добавил в код подсказку для проверки и запроса разрешения на чтение (на данный момент), но подсказка о предоставлении никогда не появляется:
PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.StorageRead>();
if (status == PermissionStatus.Denied)
{
await DisplayAlert("Alert", "Permission Denied", "OK");
// Ask for permission
status = await Permissions.RequestAsync<Permissions.StorageRead>();
}
if (status == PermissionStatus.Granted)
{
var files = Directory.GetFiles("/storage/emulated/0/Android/data", "*");
}
В настройках моего устройства> Приложения> Информация о приложении> Мое приложение> Разрешения: разрешения вообще не указаны.
Любые подсказки? Я выдергиваю остальные волосы уже несколько дней!
Возможно, я ошибаюсь в своем подходе, но я пытаюсь читать/записывать на внешнее хранилище в Android.
РЕДАКТИРОВАТЬ : Мой путь был неправильным. Адрес моей SD-карты: /storage/3439-3532/. Я могу успешно перечислить его каталоги, но при попытке доступа к файлам у меня возникает ошибка отказа в доступе:
string[] dirs1 = Directory.GetDirectories("/storage/3439-3532/", "*"); // works OK
string[] dirs2 = Directory.GetDirectories("/storage/3439-3532/BEB/", "*"); // works OK
string[] theFiles = Directory.GetFiles("/storage/3439-3532/BEB/", "*"); // KO !
Спасибо Джейсон. Я взглянул на репозиторий SafMaui. Он работает, но позволяет мне выбрать только один файл, точно так же, как FilePicker, который я использовал сначала. Я не могу понять это, так как не могу перечислить файлы, присутствующие в каталоге.
в вашем вопросе явно упоминается «чтение/запись», а не «перечисление содержимого папки»
действительно, извините. Я изменил заголовок вопроса, я думал, что его содержание было достаточно явным
Вы можете проверить это Как использовать разрешение Android MANAGE_EXTERNAL_STORAGE с MAUI?
Я не смог это реализовать. Это странно: мне удалось быстро получить список каталогов, используя Directory.GetDirectories("/storage/3439-3532/", ""). Однако попытка получить файлы каталога с помощью Directory.GetFiles("/storage/3439-3532/DCIM", "") приводит к ошибке "Отказано в доступе". Попытка создать новый каталог с помощью Directory.CreateDirectory("/storage/3439-3532/BEB"); слишком.
Думаю, я понял. Я должен реализовать права по-разному: В моем манифесте Android требовалось только MANAGE_EXTERNAL_STORAGE:
<uses-permission android:name = "android.permission.MANAGE_EXTERNAL_STORAGE"/>
В моем Android>MainActivity.cs я добавил новое намерение. При первом запуске приложение запросит разрешение:
public class MainActivity : MauiAppCompatActivity
{
// Added this v
protected override void OnCreate(Bundle savedInstanceState)
{
if (!Android.OS.Environment.IsExternalStorageManager)
{
Intent intent = new Intent();
intent.SetAction(Android.Provider.Settings.ActionManageAppAllFilesAccessPermission);
Android.Net.Uri uri = Android.Net.Uri.FromParts("package", this.PackageName, null);
intent.SetData(uri);
StartActivity(intent);
}
base.OnCreate(savedInstanceState);
}
}
Теперь я могу перечислить нужные мне файлы, создать новые каталоги, новый файл и т. д.
string[] theFiles = Directory.GetFiles("/storage/3439-3532/DCIM/Camera", "*");
Directory.CreateDirectory("/storage/3439-3532/BEB");
using FileStream outputStream = File.OpenWrite("/storage/3439-3532/BEB/test.txt");
using StreamWriter streamWriter = new StreamWriter(outputStream);
await streamWriter.WriteAsync("OKAY");
Я все еще нахожу жестко закодированную часть /storage/thingy/ уродливой, но пока этого достаточно.