Как реализовать работу с файловой системой в Android?

Работа с файловой системой в Android требует понимания где и как хранить данные, учитывая:

  • Версию Android (начиная с Android 10 — ограничения Scoped Storage).

  • Доступность памяти (внутренняя vs внешняя).

  • Тип данных (личные, кэш, временные, общие).

Android предоставляет API для безопасной работы с внутренними и внешними хранилищами, с учётом прав доступа и контекста приложения.

📁 Основные типы хранилищ

Тип хранилища Где находится Доступность Удаляется при удалении приложения
Внутреннее /data/data/<package> Только приложению ✅ Да
--- --- --- ---
Внешнее (scoped) /storage/emulated/0/Android/... Только приложению ✅ Да (в Android/)
--- --- --- ---
Внешнее (общие папки) /storage/emulated/0/Downloads, Pictures, и т. д. 🔓 Может требовать разрешения ❌ Нет
--- --- --- ---

🔹 1. Внутреннее хранилище (Internal Storage)

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

📌 Чтение/запись файлов:

// Создание файла
val file = File(context.filesDir, "config.txt")
file.writeText("Hello")
// Чтение
val content = file.readText()

📌 Каталоги:

  • filesDir — для файлов.

  • cacheDir — для кэша.

  • getDir(name, Context.MODE_PRIVATE) — кастомная папка.

🔹 2. Внешнее хранилище (External Storage)

Начиная с Android 10 используется Scoped Storage — доступ к файлам ограничен.

📁 Доступ к приватной папке приложения:

val file = File(context.getExternalFilesDir(null), "myfile.txt")
file.writeText("Data")

📌 Специальные папки:

  • getExternalFilesDir(Environment.DIRECTORY_PICTURES)

  • getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS)

  • externalCacheDir

📂 Доступ к общим файлам (например, папка Downloads)

С Android 10+ для работы с общими папками (вне Android/) используют Storage Access Framework или MediaStore.

✔ Через Storage Access Framework (SAF):

val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/plain"
putExtra(Intent.EXTRA_TITLE, "newfile.txt")
}
startActivityForResult(intent, CREATE_FILE_REQUEST_CODE)

После выбора — работа через Uri:

val outputStream = contentResolver.openOutputStream(uri)
outputStream?.write("data".toByteArray())

✔ Через MediaStore (для медиафайлов):

val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "image.jpg")
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
}
val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
val stream = contentResolver.openOutputStream(uri!!)
stream?.use {
it.write(imageBytes)
}

🔐 Разрешения

С Android 6.0 (API 23+) — runtime permissions:

&lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/&gt;
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"/>

⚠️ С Android 10+ доступ к файлам вне getExternalFilesDir требует:

&lt;application android:requestLegacyExternalStorage="true" /&gt;

(устарело с Android 11)

Удаление файлов

val file = File(context.filesDir, "config.txt")
if (file.exists()) {
file.delete()
}

Для файлов по Uri — через ContentResolver.delete(uri, null, null)

📌 Где что хранить

Задача Рекомендованное место
Настройки и сессии SharedPreferences или filesDir
--- ---
Картинки и медиа MediaStore + getExternalFilesDir()
--- ---
Кэш, временные файлы cacheDir или externalCacheDir
--- ---
Долгосрочные файлы пользователя getExternalFilesDir() или SAF/MediaStore
--- ---
Конфиденциальные данные Внутреннее хранилище + шифрование
--- ---

Итого

Работа с файловой системой в Android реализуется через:

  • File API — для внутреннего и scoped-хранилища.

  • Storage Access Framework — для запроса доступа к общим файлам.

  • MediaStore — для медиафайлов и интеграции с галереей.

  • С Android 10+ — жёсткие ограничения, требующие использования современных API.

Разработка под Android требует учитывать как ограничения ОС, так и права доступа пользователя к файлам.