autumn-2930420_1280

Продолжение.

Как думают пользователи о «внешнем хранилище» ?

Многие пользователи Android-устройств не знают, что такое «внешнее хранилище». В пользовательском интерфейсе устройства нет ничего, что обязательно будет использовать этот термин. В лучшем случае ваши пользователи будут думать, что SD-карта является внешним хранилищем. Это не совсем так.

За исключением Android 4.4+, и в этом случае ответ является лишь частично правильным.

 

Что Google считает «внешним хранилищем» ?

В документации Android SDK «внешнее хранилище» определяется так:

Каждое Android-совместимое устройство поддерживает общую «внешнюю память», которую вы можете использовать для сохранения файлов. Это может быть съемный носитель (например, SD-карта) или внутреннее (несъемное) хранилище. Файлы, сохраненные во внешнем хранилище, world-readable и могут быть изменены пользователем при подключении как USB mass storage для передачи файлов на компьютер.

Большая часть того, что было написано в документации и в других местах, касается внешнего хранилища, было для Android до Android 4.4.

В те последние дни прошлого года существовал single volume, известный как «внешнее хранилище», и он был эффективно определен как «вещь, которая появляется, когда пользователь подключает свое устройство к компьютеру с помощью USB-кабеля». Даже это было не совсем точно, так как некоторые производители также позволяли доступ к съемным носителям своих устройств через USB-кабель. И Android 4.4 добавила еще больше непоняток с точки зрения съемных носителей … вот почему сменные носители будут рассмотрены в следующем блогпосте.

Для целей этого поста в блоге — и в соответствии с тем, что будет указано в большинстве других письменных материалов — «внешнее хранилище» определяется как дерево каталогов, возвращаемое Environment.getExternalStorageDirectory().

Из оф.доки:

Примечание. Не смущайтесь слова «внешний» здесь. Этот каталог лучше воспринимать как media/shared память. Это файловая система, которая может хранить относительно большой объем данных и совместно используется во всех приложениях (permissions не применяются). Традиционно это SD-карта, но она также может быть реализована как встроенное хранилище в устройстве, которое отличается от защищенного внутреннего хранилища и может быть смонтировано как файловая система на компьютере.

 

Много мест, где хранится внешнее хранилище

Внешнее хранилище, как перекати-поле, идет туда, где ветер дует.

В устройствах Android 1.x и большинстве 2.x внешнее хранилище, как правило, представляет собой некоторую форму съемных носителей, как правило, микро SD-карт. Что еще более важно, для всех устройств Android 1.x и 2.x внешнее хранилище было отдельным разделом с отдельной файловой системой. В то время как несколько устройств Android 2.3 решили использовать встроенную флешку для внешнего хранилища, это был еще отдельный раздел из раздела, в котором хранилось внутреннее хранилище. В результате мы оказались с устройствами, которые могли бы рекламировать хранилище на несколько ГБ, но это хранилище, как правило, было главным образом для внешнего хранилища, так как разделы не могли быть изменены обычными пользователями.

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

 

Читать ещё :   Использование Android Jetpack для ускорения разработки приложений

Много path, где хранится внешнее хранилище

Для нас, как разработчиков, фактический путь, по которому есть доступ к этому магическому «внешнему хранилищу» был изменен с годами, от /sdcard,  и местоположений  /storage, до текущего /mnt/shell/emulated/0.

И так же, как вторичные пользователи планшета Android 4.2+ получают собственное внутреннее хранилище, они получают свое собственное внешнее хранилище с собственным корневым каталогом. Следовательно, как я уже говорил:

NEVER HARDCODE PATHS

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

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

Позже Google предложил больше организованности:

  • getExternalFilesDir() и getExternalCacheDir() в Context, указывая на каталог приложения на внешнем хранилище, который будет удален, когда приложение будет удалено
  • Environment.getExternalStoragePublicDirectory(), для централизованных мест для хранения известных типов файлов, таких как фотографии и фильмы

Обратите внимание, что Context методы имеют множественное число в Android 4.4+ (getExternalFilesDirs() и getExternalCacheDirs()), которые связаны со сменными носителями, которые мы изучим завтра.

 

Внешнее хранилище и разрешения

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

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

Тем не менее, любое приложение все равно может читать из внешнего хранилища.

Android 4.4 начал применять разрешение READ_EXTERNAL_STORAGE, поэтому вы даже не можете читать из внешнего хранилища, если у вас нет определенного разрешения.

Обратите внимание, что WRITE_EXTERNAL_STORAGE подразумевает READ_EXTERNAL_STORAGE, поэтому вам нужен только один из них, а не оба.

И для getExternalFilesDir() и getExternalCacheDir() вам не нужен ни одно из этих разрешений — вы можете безнаказанно читать и писать в эти каталоги.

Android теперь имеет атрибут android:maxSdkVersion в <uses-permission>, в частности, чтобы вы могли отменить WRITE_EXTERNAL_STORAGE, если он вам больше не нужен, потому что вы работаете только с getExternalFilesDir() и getExternalCacheDir().

 

Читать ещё :   Использование Optional в Android сегодня

Исследуем внешнее хранилище

Будучи разработчиком, предполагая, что вы можете найти, где действительно хранится внешнее хранилище для вашей версии Android, вы имеете неограниченный доступ к нему из Device File Explorer в Android Studio для эмуляторов и продакшн  устройств.

Вы также можете использовать USB-кабель, как и ваши пользователи. Однако имейте в виду, что то, что представлено на интерфейсе USB, не соответствует внешнему хранилищу … но вместо этого это то, что было проиндексировано на внешнем хранилище в MediaStore. Следовательно, если вы не предпримете шаги, чтобы убедиться, что новые файлы, которые вы создали, проиндексированы, они могут быть не сразу видны.

Под капотом Android использует Media Transfer Protocol для своих USB-коммуникаций. Это обеспечивает гораздо большую гибкость, чем режим Mass Storage Mode (a.k.a., то, что используют флэш накопители), который первоначально использовал Android. Тем не менее, некоторые клиенты MTP могут кэшировать списки каталогов, поэтому даже после того, как вы получите файл, индексированный MediaStore, возможно, потребуется обновить уже подключенный клиент.

 

Как защитить свои файлы на внешнем хранилище?

В общем случае никак.

Пользователь имеет полный доступ к внешнему хранилищу, а другие приложения могут получить доступ к внешнему хранилищу, если они имеют правильные разрешения. Одна вещь, которую вы можете сделать, это использовать что-то вроде «Скрытия Facebook». Это шифрует ваши файлы на внешнем хранилище, но использует сгенерированный ключ шифрования, хранящийся во внутреннем хранилище.

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