Проблема концептуализации доступа к файловой системе Android
Я хочу, чтобы мое приложение автоматически загружало данные из файла при запуске, а затем отображало сводку этих данных для пользователя. Я думал, что это будет просто, но...
У меня почти все получилось, но я обнаружил, что было бы сложно поместить файл данных на эмулированный Android, предоставляемый Android Studio. Поэтому я поместил базовую версию файла в пакет как актив. Мой код проверен на наличие файла и, если не найден, копирует файл из ресурсов в хранилище телефона. Пока все хорошо, но потом я понял, что это не соответствует требованиям, потому что пользователь не может настроить файл (через другое приложение или поместив новую версию файла на свой телефон).
Я обнаружил, что мне нужно использовать "внешнее" хранилище (которое на самом деле не внешнее, а просто общее / публичное хранилище). Поэтому я использовал getExternalStoragePublicDirectory(), чтобы получить доступ к папке "Документы". В той части моего кода, которая копирует файл ресурсов в папку "Документы", я получаю "java.io.IOException: Нет такого файла или каталога", когда я пытаюсь создать целевой файл.
Это действительно потрясло меня на некоторое время, так как я предшествовал ему с помощью mkdirs(), чтобы убедиться, что папка (и) существует, и я пытался создать файл в первую очередь.
После большого количества возни с S/O, похоже, моя проблема может заключаться в том, что у меня нет прав на чтение / запись в папке "Документы". Так что здесь я не могу понять, как это должно работать.
В OnCreate() моей Activity я хочу загрузить данные из моего файла. Но мне нужно сначала проверить разрешения. Это гарантированно потерпит неудачу в первый раз, потому что пользователь никогда не давал моему приложению такого разрешения раньше.
Итак, мне нужно запросить разрешение. Но это означает, что я больше не могу загружать свои данные в методе OnCreate(), поскольку я получу ответ пользователя асинхронно, в методе обратного вызова (onRequestPermissionsResult).
Если пользователь говорит "Нет" на мой запрос, я должен убедиться, что приложение корректно завершает работу. Если она говорит "Да", тогда... что? На данный момент я нахожусь в обратном вызове, и мой метод OnCreate() больше не работает. Как я могу вернуться к настройке своей активности?
Если я загружаю файл данных в методе обратного вызова, это работает только для первоначального случая, когда пользователь должен дать разрешение. Но после этого мое приложение (скорее всего) не потеряет разрешение, поэтому моему приложению не нужно будет запрашивать его. В этом случае обратный вызов никогда не будет выполнен. Так что мой файл данных должен быть загружен... где?
Но все это происходит только в том случае, если пользователь работает под управлением Android 6.0 или выше. Если это более ранняя версия Android, то мое приложение может загрузить данные в метод OnCreate() моей Activity.
Ох... у меня болит голова!
Как все это должно работать? Мне не нужна ссылка на соответствующие методы. Мне нужна концептуальная модель - диаграмма действительно поможет!
Вот решение на диаграмме: Концептуальная диаграмма разрешений
1 ответ
Как я могу вернуться к настройке своей активности?
Переместите код "Настройка моей активности", который зависит от файлового ввода-вывода, в отдельный метод. В onCreate()
проверьте, есть ли у вас разрешение, и если да, вызовите этот метод для настройки своей активности. Если нет, позвоните requestPermissions()
, В onRequestPermissionsResult()
Если у вас есть разрешение, вызовите этот метод для настройки своей активности.
Посмотрите этот пример приложения, которое выполняет дисковый ввод-вывод из внешнего хранилища, используя разрешения времени выполнения. Логика обработки разрешений изолирована в AbstractPermissionsActivity
оставляя основной класс деятельности для обработки реальной бизнес-логики.
Если это более ранняя версия Android, то мое приложение может загрузить данные в метод OnCreate() моей Activity.
Ну, вы должны делать этот дисковый ввод-вывод в фоновом потоке. Вы можете начать этот ввод / вывод с onCreate()
,
Если вы используете ContextCompat
а также ActivityCompat
для проверки и запроса разрешений, соответственно, ваш код будет "делать правильные вещи" на старых устройствах, так как эти классы выполняют проверку версий для вас.