Что значит внешнее хранилище недоступно. Доступ к внешнему хранилищу – разработка игр для ос android. Просмотр перечня элементов, которыми вы поделились

Фон

У Android было много изменений относительно того, как обращаться с SD-картой и хранилищем в целом:

  • API 3 - вы получаете доступ, не требуется разрешение
  • API 4-15 - вам нужно использовать WRITE_EXTERNAL_STORAGE, и вы получите доступ.
  • API 16-18 - если вы хотите только читать, используйте READ_EXTERNAL_STORAGE
  • API 19-20 - вы не можете читать или записывать на вторичное внешнее хранилище (SD-карту), если ваше приложение не является системным приложением или у вас есть root.
  • API 21-22 - чтобы получить доступ к SD-карте, вам нужно попросить у пользователя разрешения и использовать API DocumentFile вместо File API. Это вызвало множество вопросов, поскольку я писал о , и .

Начиная с API 23 (Android 6), похоже, что все снова меняется...

Проблема

Для API 23 есть как минимум 2 вещи, которые новы и связаны с памятью:

  • " . Пользователь может по желанию сделать SD-карту чем-то вроде первичное внешнее хранилище.
  • Как часть нового механизма разрешений (запрашивая разрешения во время выполнения), похоже, что хранилище также разрешение, которое пользователь должен подтвердить. Это для READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE

Так как у Android нет устройства с SD-картой, и поскольку сам эмулятор действительно не имеет возможности использовать SD-карту, все еще невозможно узнать, что происходит.

Вопросы

    Будет ли SD-карта получить доступ с использованием File-API вместо DocumentFile?

    Если мне нужен доступ ко всем внешним путям хранения (включая SD-карту), значит ли это, что мне нужно дважды запрашивать эти разрешения: один для основного внешнего хранилища и один для SD-карты?

    Доступны ли файлы на SD-карте каким-либо образом до предоставления разрешения на использование вручную?

    Предположим, что пользователь решил использовать "Adoptable Storage Devices" , что это означает для различных функций, которые извлекают пути к файлам приложений? Например: getFilesDir, getExternalFilesDir,...? Из-за этого изменилось бы другое из getExternalFilesDirs?

    Что происходит с файлами приложения, когда пользователь перемещает приложение с/на SD-карту (используя "Adoptable Storage Devices")? Как насчет файлов приложений на SD-карте? Останутся ли они? Или они куда-нибудь переместятся?

    Например, если приложение имеет файл "file1.txt" на SD-карте, на пути "/storage/extSdCard/Android/data/appPackageName", и у него есть файл "file2.txt" (или даже одно и то же имя) на основном внешнем хранилище по пути "/storage/emulated/0/Android/data/appPackageName". После переключения, что произойдет для этих файлов? Как бы они слились в одну папку, если вообще?

    При перемещении приложения на SD-карту (используя "Adoptable Storage Devices") означает ли это, что внутреннее хранилище не будет использоваться?

    1 ответ

    Позвольте мне ответить на Удостоверяемые устройства хранения :

    1. Предположим, что пользователь решил использовать "Adoptable Storage Devices" , что это означает для различных функций, которые извлекают пути файлы приложений? Например: getFilesDir, getExternalFilesDir,...? Из-за этого изменится другой из getExternalFilesDirs?

    Когда пользователь выбирает использовать SD-карту как "Adoptable Storage Device" (формат как внутренний), теперь это означает, что SD-карта доступна только в качестве внутреннего хранилища, то есть нет SD-карты, доступной для хранения загруженных файлов. Изменения путей в путях, возвращаемых связанными методами, не будут. Например: getExternalFilesDir() будет отображать только внешний путь хранения, если пользователь отформатировал свою SD-карту как "Adoptable Storage Devices" . Путь к карте SD не будет доступен.

    1. Что происходит с файлами приложения, когда пользователь перемещает приложение с/на SD-карту (используя "Adoptable Storage Devices")? Какие о файлах приложений на SD-карте? Останутся ли они? Или они двигаться где-то? Например, если приложение имеет файл "file1.txt" на SD-карта, по пути "/storage/extSdCard/Android/data/appPackageName", и он имеет файл "file2.txt" (или даже одно и то же имя) на первичном внешнее хранилище на пути "/Хранение/эмулировать/0/Android/данные/appPackageName". После переключения, что будет с этими файлами? Как они слились бы в один папка, если вообще?

    Когда пользователь выбирает свою SD-карту в качестве "Adoptable Storage Devices" , пользователю необходимо отформатировать SD-карту как внутреннее хранилище, используя "Формат как внутренний" . Формат означает, что все данные/файлы, хранящиеся на SD-карте, будут удалены. Аналогично, когда пользователь хочет удалить свою SD-карту из "Adoptable Storage Devices" , пользователю снова нужно отформатировать свою SD-карту в качестве переносного хранилища, используя опцию "Формат как переносная" .

    Хранилище конфигурации в 1С 8.2 и 8.3 — это инструмент для групповой разработки решения, встроенный в платформу 1С: Предприятие 8. Хранилище позволяет вести многопользовательскую разработку решений неограниченным количеством пользователей. С его помощью можно увидеть полную историю разработки конфигурации и каждый шаг разработчиков в подробностях.

    Рассмотрим настройки и работу с хранилищем конфигурации подробнее.

    Хранилище, по сути, это база данных, где хранятся изменения конфигурации. Каждый из разработчиков работает со своей информационной базой, подключенной к хранилищу. Рабочая база так же может быть подключена к хранилищу. Лучше всего общая схема изображена на этой картинке:

    Так же в этой БД хранится информации о том, кем захвачен тот и или иной объект. Захват объекта — это метка, устанавливаемая разработчиком. Установленный захват позволяет избежать коллизий при групповой разработке. Пока объект захвачен, никто не может его редактировать.

    Захватить можно как объект целиком (рекурсивно), так и отдельно объект или формы.

    После того как разработчик произвел какие-то действия над объектом, он обязан поместить доработки в хранилище. И тем самым снять пометку о том, что объект захвачен.

    Как создать хранилище 1С

    Создать хранилище достаточно просто, для этого необходимо выбрать в меню «Конфигурация — Хранилище конфигурации» пункт «Создать хранилище». В появившемся меню достаточно указать путь к будущему расположению хранилища и логин/пароль пользователя-администратора:

    При создании сделайте обязательно резервную учетную запись с административными правами — очень часто это выручает.

    Как подключиться к хранилищу 1С

    Чтобы подключиться к хранилищу конфигурации, нужно выбрать в меню в меню «Конфигурация — Хранилище конфигурации» пункт «Подключиться к хранилищу». В появившемся окне необходимо указать путь к хранилищу и логин/пароль пользователя, нажать «Подключиться»:

    Получите 267 видеоуроков по 1С бесплатно:

    В момент подключения Ваша конфигурация заменится конфигурацией из хранилища, будьте внимательны.

    Администрирование хранилища конфигурации 1С

    Для администрирования хранилища 1С необходимо выбрать в меню конфигурации следующий пункт — «Конфигурация — Хранилище конфигурации — Администрирование»:

    • На вкладке «Пользователи» можно добавить или удалить новых пользователей, а также определить состав прав для каждого из них.
    • На вкладке «Подключения» можно просмотреть всех пользователей, подключившихся к хранилищу, по необходимости отключить их.
    • На вкладке «Отмена захвата» Вы можете снять захват любого пользователя на определенный объект, если конечно же Вы имеете права на это.

    Как просмотреть историю хранилища 1С

    Для просмотра истории надо зайти в меню «Конфигурация — Хранилище конфигурации», выбрать пункт «История хранилища»:

    В истории хранилища 1С можно увидеть, когда, кем и что было изменено.

    Разработка с хранилищем 1С 8.3

    Работу с хранилищем условно можно разделить на основные действия:

    • конфигурации из хранилища конфигурации 1С;
    • обновить статусы хранилища 1С;
    • захват в хранилище;
    • помещение в хранилище.

    Остановимся подробнее на каждом действии:

    Обновить статусы хранилища 1С

    Производит получение последних статусов объектов (захвачен или нет).

    Вызывается: «Конфигурация — Хранилище конфигурации — Обновить статусы».

    Обновление конфигурации из хранилища конфигурации 1С

    Действие позволит получить все измененные объекты конфигурации, которые были помещены в хранилище. Выполнение данной команды так же обновляет статусы объектов.

    Вызывается: «Конфигурация — Хранилище конфигурации — Обновить конфигурацию из хранилища».

    Захват в хранилище конфигурации 1С

    С помощью этой команды можно заблокировать изменение данного объекта для других разработчиков: пока объект захвачен Вами, никакой пользователь не может изменить его до тех пор, пока Вы не поместите объект обратно.

    Произвести захват можно, вызвав правой кнопкой контекстное меню у объекта метаданных:

    В открывшемся окне можно установить некоторые настройки:

    • Выполнять рекурсивно — позволяет захватить все подчиненные объекты — формы и т.д.
    • Разрешать получать захваченные — позволяет получать другим пользователям промежуточные версии объекта

    Помещение в хранилище 1С

    После изменения объекта его необходимо поместить обратно в хранилище, делается это так же, как захват, только выбирается пункт «Поместить в хранилище»:

    При помещении обязательно заполняйте поле «комментарий», это очень важно при групповой разработке. Через полгода Вы и не вспомните, зачем производили те или иные действия. Так же, как у захвата, у помещения есть свои специфичные настройки:

    • Выполнять рекурсивно — позволяет поместить все подчиненные объекты — формы и т.д.
    • Оставить захваченными — позволяет поместить «промежуточную» версию объекта, оставив при этом захват пользователем

    Как добавить новый объект в хранилище 1С

    Облачные сервисы хранения данных стали настоящей панацеей для всех, кто хотел получать доступ к своим данным с любого устройства из любой точки пространства. Мы с радостью переместили свои данные в облака и успешно пользуемся ими, лишь иногда с опаской читая очередную новость о хаках iCloud и Dropbox. Кому-то изначально не даёт покоя тот факт, что облако контролирует «кто-то», но не сам пользователь. Именно такие энтузиасты сделали OwnCloud.

    Что это такое

    «Собственное облако» представляет собой не что иное, как персональное хранилище, работающее на собственном веб-сервере или сайте. Главная фишка OwnCloud в том, что он бесплатный и опенсорсный. В целом при наличии вышеупомянутой площадки для размещения пользователю потребуется примерно 5 минут на разворачивание собственного Dropbox-like хранилища, и без хитроумного кодинга - каких-либо специфических знаний не нужно. В довесок пользователь получает доступ к приложениям (текстовые редакторы, списки задач и прочие полезные штуки), которые создают другие участники проекта для собственных нужд.

    Хотя ресурсы прекрасно подходят для хранения изображений и звуков нашего приложения, иногда необходимо сохранять информацию и позже загружать ее вновь. Простой пример – работа с таблицей лучших результатов.

    Android предлагает различные способы для реализации этого; вы можете использовать общие настройки приложения, маленькую базу данных SQLite и т. д. У всех этих возможностей есть общая черта – они не обрабатывают большие двоичные файлы. Для чего нам это может понадобиться? Хотя мы можем указать системе, чтобы она устанавливала приложение во внешнее хранилище (и таким образом не тратить память внутреннего хранилища), это будет работать только в версиях Android начиная с 2.2. В более старых версиях ОС все данные приложения будут храниться во внутренней памяти устройства. Теоретически мы могли бы включить код нашего приложения в АРК-файл и загружать все ресурсы с сервера на карту памяти SD при первом запуске программы. Многие известные игры для Android так и делают.

    Существуют и другие сценарии, в которых нам необходим доступ к карте памяти (которая, в общем-то, является синонимом термина внешнее хранилище для современных устройств). Мы могли бы позволить нашим пользователям создавать собственные уровни во внутреннем редакторе. После создания нам будет необходимо их где-то хранить, и SD-карта прекрасно для этого подходит. Итак, мы не будем использовать необычные механизмы, предлагаемые Android для хранения настроек приложения, и рассмотрим вместо этого механизм реализации чтения и записи файлов на карте SD.

    Первое, что нам необходимо сделать, – запросить разрешение на доступ к внешнему хранилищу. Это делается в файле манифеста с помощью уже рассмотренного нами элемента .

    Далее нужно проверить, доступно ли нам в данный момент внешнее хранилище. Например, при работе с AVD у вас есть возможность обойтись без эмулирования наличия карты памяти – тогда приложение ничего не сможет туда записывать. Другая причина не получать доступ к SD-карте – его занятость другим процессом (например, просмотра его пользователем через USB). Вот так мы проверяем состояние карты памяти;

    В результате мы получаем строку. Класс Environment определяет набор констант, одна из которых называется Environment. MEDI AMOUNTED (ее значение – тоже строка). Если вышеуказанный метод возвращает именно эту константу, это значит, что мы имеем полный доступ (чтение и запись) к внешнему хранилищу. Обратите внимание – на самом деле вам необходимо использовать метод equals для сравнения двух строк; оператор равенства в таких случаях не всегда дает верные результаты.

    Итак, мы узнали, что обладаем полным доступом к внешнему хранилищу, и теперь нам необходимо получить название его корневой директории. Если нам нужен доступ к определенному файлу, путь к нему необходимо определять относительно корневого каталога. Для этого мы применим другой статический метод класса Environment:

    С этого момента мы можем использовать стандартные Java-классы для чтения и записи файлов. Создадим небольшой пример, реализующий запись файла на карту памяти, его чтение, демонстрацию его содержимого в TextView и удаление его с карты. В листинге 4.8 показан исходный код для этого.

    Листинг 4.8. Активность ExternalStorageTest package com.bad.ogi с.androi dgames;

    Сначала мы проверяем физическую доступность SD-карты (если проверка не удалась, на этом все и заканчивается). Далее получаем корневой каталог хранилища и создаем новый экземпляр объекта File, указывающий на файл, который мы создадим в следующем выражении. Метод writeTextFi 1е использует стандартные Java-классы ввода-вывода для реализации наших целей. Если файл еще не существует, метод создаст его; в ином случае он перепишет существующий. После успешной записи текста в файл на карте мы вновь его считываем оттуда и устанавливаем в качестве содержимого TextVi ew. Финальный шаг – удаление файла из внешнего хранилища. Все действия совершаются с соблюдением необходимых мер предосторожности, благодаря которым сообщения о проблемах также выводятся в TextView. Рисунок 4.11 демонстрирует вывод активности.

    Из этого урока необходимо извлечь следующие моменты.

    Не работайте с файлами, которые вам не принадлежат. Пользователи очень рассердятся, если вы удалите фотографии с их последней вечеринки.

    Всегда проверяйте доступность внешнего хранилища.

    Не связывайтесь со служебными файлами во внешнем хранилище. Я серьезно.

    Рис. 4.11. Послание от веселого Роджера

    Увидев, как легко удалить все файлы из внешнего хранилища, вы должны подумать дважды, создавая и размещая на Android Market приложение, запрашивающее доступ к карте SD, – ведь после инсталляции оно будет иметь полный доступ ко всем файлам.

    Обработка звука

    Android предлагает простые в применении API для воспроизведения звуковых эффектов и музыкальных файлов – как раз то, что нам нужно для написания игры. Рассмотрим их.

    Мое приложение хранит файлы во внутреннем каталоге хранилища (/Android/data/com.mycompany.myapp/files, как было возвращено getFilesDir()), и я хотел бы разрешить пользователям обращаться к этим файлам непосредственно из управления файлами приложение на своем мобильном устройстве или приложение Android File Transfer для рабочего стола.

    2 ответов

    Я более подробно рассмотрел результат getFilesDir() vs getExternalFilesDir() и обнаружил, что getFilesDir() возвращает /data/data//files , а getExternalFilesDir() возвращает /Android/data//files . Я думал, что файлы приложений, которые я просматривал в /Android/data , были внутренними каталогами хранилища, но теперь я вижу, что это фактически внешние каталоги хранения.

    Если внутренние папки хранения никогда не доступны для обычных пользователей, я хочу, чтобы в документации говорилось, что вместо того, чтобы говорить, что они недоступны "по умолчанию". По крайней мере, для меня, говоря "по умолчанию", подразумевается, что поведение по умолчанию может быть изменено.

    В любом случае, я протестировал и подтвердил, что если я удалю свое приложение, файлы, сохраненные в getExternalFilesDir() , будут удалены автоматически. Таким образом, это соответствует моей потребности в местоположении хранилища, которое явно связано с приложением (использует имя конкретного приложения и удаляется с помощью приложения), но доступно пользователям для случайного ручного управления файлами.

    Вот сравнение, которое может быть полезно для кого-то другого, читающего это:

    Я думаю, что вы запутались в документации разработчиков, я не могу вас обвинить, это не лучшая документация, которую я когда-либо читал. В любом случае, Android предоставляет два способа сохранения файлов в файловой системе:

    • Использование внутреннего хранилища
    • Использование внешнего хранилища

    Внутреннее хранилище ВСЕГДА доступно и доступно ТОЛЬКО вашему приложению, никакое другое приложение в системе не может получить доступ к файлам, сохраненным в этом разделе.

    Теперь я думаю, что вам нужно Внешнее хранилище , потому что оно "доступно для чтения" и доступно любому пользователю и любым приложениям. Недостатком является то, что он может быть недоступен, так как пользователь может установить его на USB-устройство, которое может быть удалено пользователем в любое время.

    Вы не должны использовать ни MODE_WORLD_WRITEABLE , ни MODE_WORLD_READABLE , как указано в документации, потому что это очень опасно. Кроме того, эти константы устарели, поскольку уровень API 17

    Если вам нужно сделать ваши файлы общедоступными, сохраните их в Внешнем хранилище . Вам нужно будет объявить разрешение в вашем файле манифеста, чтобы избежать сбоя приложения при каждом доступе к Внешнему хранилищу ...

    поскольку Внешнее хранилище может быть недоступно, вам нужно будет определить его состояние перед выполнением какой-либо операции, иначе ваше приложение выйдет из строя...

    Public enum StorageState{ NOT_AVAILABLE, WRITEABLE, READ_ONLY } public StorageState getExternalStorageState() { StorageState result = StorageState.NOT_AVAILABLE; String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return StorageState.WRITEABLE; } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { return StorageState.READ_ONLY; } return result; }

    Более подробная информация о документации и вещах, о которых вы должны знать. Например, вы можете предоставить владельцам своих файлов эти файлы, чтобы при удалении приложения система могла автоматически удалять эти файлы. Для получения дополнительной информации см. Документацию на сайте разработчиков Android

    поделиться