ОАО «Российская Авиакомпания ЭРЛЕН»

Russian Airlines Company "Airlen"

Ваш внешний IP: 3.239.76.25

Демистификация внутренней и внешней памяти в современном Android

Демистификация внутренней и внешней памяти в современном Android

Том Колвин

7 минут чтения

16 января

Обновлено 6 февраля 2023 г.

Изображение SD-карты на цветном фоне
Изображение Рави Шармы

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

Давайте отправимся в путешествие, чтобы понять, почему существуют эти варианты, какой вариант вам следует выбрать и какие есть лучшие альтернативы.

Раньше Android был простым, но безумно небезопасным

В старые времена у внутреннего и внешнего выбора были разные цели:

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

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

Поэтому, если вы хотели хранить большой объем данных — скажем, вы писали приложение для фотографий — у вас действительно был выбор только во внешнем хранилище. Поэтому приложения часто запрашивали разрешение на доступ к внешнему хранилищу (через разрешения READ_EXTERNAL_STORAGE и WRITE_EXTERNAL_STORAGE).

Но это было крайне небезопасно. Эти разрешения на внешнее хранилище позволят приложению читать/записывать файлы в любом месте на SD-карте. Таким образом, все ваши фотографии стали доступны любому приложению, желающему записать свои данные во внешнее хранилище. А поскольку разрешения на внешнее хранилище так часто запрашивались приложениями, пользователи предоставляли их без какого-либо реального рассмотрения. Отслеживайте вредоносные приложения, которые крадут ваши данные без вашего ведома.

Android KitKat: упрощенные разрешения повысили безопасность (!!)

Вопрос : Как можно решить проблему безопасности, ослабив разрешения, необходимые для каких-либо действий?

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

Демистификация внутренней и внешней памяти в современном Android
Android KitKat улучшил безопасность хранилища, ослабив разрешения (фото: Google)

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

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

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

Эмулированное внешнее хранилище: когда внутреннее хранилище становится внешним

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

И телефоны постепенно перестали предлагать внешнее хранилище. Это вызвало проблему со старыми приложениями, которые ожидали, что только внешнее хранилище будет достаточно большим для их нужд, и слепо использовали getExternalFilesDir() .

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

Начиная с API 21, приложения могут использовать Environment.isExternalStorageEmulated() , чтобы определить, имеет ли устройство физическое или эмулированное внешнее хранилище. Для подавляющего большинства современных Android-устройств он будет эмулироваться.

Приемлемое внешнее хранилище: когда внешнее хранилище становится внутренним

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

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

Плохие моменты : принятая SD-карта, скажем, неразрывно связана с этим телефоном. Удалите его, и ваш телефон станет странным : вы, по сути, удалили случайный фрагмент его приложений и данных. (Случайно, потому что ОС, а не пользователь выбирает, будет ли что-то установлено или сохранено во внутренней или принятой памяти.) Я не могу представить, чтобы какая-либо ОС могла справиться с этим очень хорошо.

Scoped Storage в Android 10 полностью изменил внешнее хранилище

Логотип Android 10
Android 10 полностью изменил принцип работы хранилища (изображение: Google)

Android 10 представил Scoped Storage для внешнего хранилища. По сути, это сделало безопасность внешнего хранилища очень похожей на внутреннюю память. Приложения получат свой собственный каталог, к которому они смогут обращаться (чтение/запись) без разрешения, и ни одно другое приложение не сможет этого сделать (кроме см. ниже).

Проблема с Scoped Storage заключалась в том, что в нем не учитывались некоторые важные варианты использования, которые ранее требовали бесплатного доступа к общему хранилищу. Например, как насчет доступа к фотогалерее пользователя? Эти варианты использования рассматривались в индивидуальном порядке. Они следующие:

Разрешение пользователю выбирать из галереи фотографий

Используйте средство выбора фотографий , никаких разрешений не требуется. (См. мою статью об использовании Photo Picker с Kotlin + Compose ).

Анимация, показывающая, как работает средство выбора фотографий в Android 11+.
Android Photo Picker, изображение предоставлено Google

Обратите внимание, что это доступно только на Android 11+.

Запись фотографий в библиотеку пользователя

Используйте API-интерфейсы MediaStore . Для записи новых фотографий не требуется никаких разрешений.

Чтение фотографий из библиотеки пользователя

Также API MediaStore. Никаких разрешений не требуется, если вы получаете доступ только к файлам, созданным вашим собственным приложением. Если вы хотите получить доступ ко всей библиотеке, вам потребуются следующие разрешения:

<!-- Требуется, только если вашему приложению требуется доступ к изображениям или фотографиям 
     , созданным другими приложениями. --> 
< uses-permission  android:name = "android.permission.READ_MEDIA_IMAGES" /> 

<!-- Требуется, только если вашему приложению требуется доступ к видео 
     , созданным другими приложениями. --> 
< uses-permission  android:name = "android.permission.READ_MEDIA_VIDEO" /> 

<!-- Требуется, только если вашему приложению требуется доступ к аудиофайлам 
     , созданным другими приложениями. --> 
< использует-разрешение  android:name = "android.permission.READ_MEDIA_AUDIO" />

<!-- Если вашему приложению не требуется доступ к медиафайлам, созданным другими приложениями, 
     вместо этого установите для атрибута "maxSdkVersion" значение "28". --> 
< использование-разрешение  android:name = "android.permission.READ_EXTERNAL_STORAGE" 
                 android:maxSdkVersion = "32" /> 

< использование-разрешение  android:name = "android.permission.WRITE_EXTERNAL_STORAGE" 
                 android:maxSdkVersion = "29" / >

Создание, чтение и запись общих документов

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

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

Доступ к большим наборам данных, кэшированным другим приложением

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

Этого можно добиться с помощью BlobStoreManager .

Полный доступ ко всему во внешнем хранилище

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

Разрешение есть MANAGE_EXTERNAL_STORAGE. Приложения должны не только объявлять это разрешение, но и указывать пользователям включать его вручную. Активируйте ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSIONнамерение сделать это, что приводит пользователя сюда:

Изображение диалогового окна разрешения управления всеми файлами
Разрешение на доступ ко всем файлам, которое пользователь должен предоставить вручную.

Отказ от ограниченного хранилища

Хотя Scoped Storage был представлен в Android 10, это было настолько значительное изменение, что оно не применялось до Android 11. Даже тогда приложения, ориентированные на API 29, могли отказаться от него, поместив его в файл манифеста <application android:requestLegacyExternalStorage="true" />. Обратите внимание, что приложения, ориентированные на API 29, не принимались в Play Store уже много лет, поэтому он, по сути, больше не поддерживается.

Итак, это вводит нас в курс дела. Текущая версия Android не претерпела существенных изменений в правах доступа к хранилищу после этого масштабного изменения в Android 10.

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

Том Колвин — технический директор Conseal Security , экспертов по тестированию безопасности мобильных приложений; и Apptaura , специалисты по разработке приложений. Свяжитесь с нами , если я могу помочь с любыми проектами по безопасности мобильных устройств или разработками!

Андроид
Разработка приложений для Android
Безопасность Android
Безопасность

Том Колвин

Автор Том Колвин

Андроид и безопасность. Технический директор Apptaura, специалисты по разработке приложений, и Conseal, эксперты по безопасности. Доступен в качестве внештатного консультанта/разработчика. Южная Англия.

Февраль 2024
Пн Вт Ср Чт Пт Сб Вс
 1234
567891011
12131415161718
19202122232425
26272829  

Сервер: 29.02.2024 08:02