Android

Перенос данных в Scoped Storage на Android: пошаговая инструкция

При переходе на Android 10+ Scoped Storage ограничивает доступ к файлам. Это руководство объясняет, как перенести существующие данные в новое пространство хранения, сохранив доступность и приватность.

Обновлено 22 июля 2026 г.
5-10 мин
Средняя
FixPedia Team
Применимо к:Android 10 (API 29)Android 11 (API 30)Android 12 (API 31)Android 13 (API 33)

Введение

С Android 10+ Google ввёл Scoped Storage — новую модель хранения, которая ограничивает прямое приложение-специфическое взаимодействие с файлами во внешней памяти. Это повышение приватности иногда приводит к «исчезновению» данных, если приложение не обновлено для работы с новой моделью. В этом руководстве вы узнаете, как перенести существующие данные в соответствующее пространство хранения, сохранив доступность и целостность файлов.

Требования

  • Устройство под управлением Android 10 (API 29) или выше (рекомендуется Android 12+ для стабильной работы File Provider).
  • Разработанный Android-код приложения (Android Studio проект), в котором нужно выполнить миграцию.
  • Доступ к компьютеру с adb (Android Debug Bridge) для массовых операций.
  • Базовое понимание Kotlin/Java и XML-разметки AndroidManifest.
  • Резервная копия важных файлов на случай непредвиденных ситуаций.

Пошаговая инструкция

Шаг 1: Проверьте текущую структуру хранения

Откройте Настройки → Хранилище → Internal storage и найдите директорию вашего приложения (обычно /storage/emulated/0/app_name/). Запишите относительный путь, поскольку он понадобится для перемещения данных.

Шаг 2: Создайте app-specific директорию с использованием File Provider

Добавьте в AndroidManifest.xml объявление провайдера:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.example.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

Создайте ресурс res/xml/file_paths.xml:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="my_files" path="."/>
    <images-path name="my_images" path="pictures/"/>
    <documents-path name="my_docs" path="Documents/"/>
</paths>

Теперь приложение может безопасно выдавать content:// URI для файлов, находящихся в этих директориях.

Шаг 3: Переместите существующие файлы в новую директорию

Для массового перемещения через ADB выполните:

adb shell "mv /storage/emulated/0/app_name/old_dir/* /storage/emulated/0/app_name/files/"

Для автоматизированного перемещения в коде Kotlin:

val src = File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "old")
val dst = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
src.listFiles()?.forEach { file ->
    val target = File(dst, file.name)
    file.copyTo(target, overwrite = true)
}

Шаг 4: Обновите URI для существующих файлов

Если приложение ранее использовало прямые file:// URI, замените их на URI, полученные через File Provider:

val uri = FileProvider.getUriForFile(this, "com.example.fileprovider", imageFile)

Теперь вы можете безопасно передавать uri в Intent или ContentResolver.

Шаг 5: Проверьте доступность через MediaStore (для медиафайлов)

Для изображений и видео добавьте записи в MediaStore:

val imageUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val values = ContentValues().apply {
    put(MediaStore.Images.Media.DISPLAY_NAME, "new_image.jpg")
    put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
    put(MediaStore.Images.Media.DATA, imagePath)
}
contentResolver.insert(imageUri, values)

Данные становятся доступны через системные приложения (Галерея, Фотографии) без дополнительных прав.

Шаг 6: Запустите приложение и проверьте работу

Запустите приложение, откройте раздел «Мои файлы» или «Галерея». Убедитесь, что все ранее существовавшие файлы доступны по тем же именам. Если что-то пропало, найдите их в DCIM, Pictures или Documents — именно туда их поместил File Provider.

Проверка результата

  • Все файлы отображаются в приложении.
  • Системные инструменты (например, файловый менеджер) также видят новые директории (/storage/emulated/0/app_name/files/).
  • URI, выданные через File Provider, открываются корректно в других приложениях.
  • Нет предупреждений о доступе к файлам в панели «Приложения → Разрешения».

Возможные проблемы

  • Потеря доступа к файлам после перезагрузки – убедитесь, что вы добавили <provider> с android:exported="false" и правильно настроили authorities.
  • Неправильные пути в MediaStore – укажите правильный MIME_TYPE и DATA; проверьте, что путь существует в файловой системе.
  • Сбой копирования через ADB – проверьте права: adb shell должен запускаться от пользователя, имеющего доступ к /storage/emulated/0.
  • Файлы всё ещё недоступны – запустите ContentResolver.loadThumbnail или MediaScannerConnection для обновления индексации.

Часто задаваемые вопросы

Почему приложения не видят мои файлы после обновления до Android 10?
Можно ли отменить миграцию, если что-то пошло не так?
Какие файлы совместимы с Scoped Storage?
Требуется ли root-доступ для переноса данных?

Полезное

Проверьте текущую структуру хранения
Создайте app-specific директорию с использованием File Provider
Переместите существующие файлы в новую директорию
Обновите URI для существующих файлов
Проверьте доступность через MediaStore (для медиафайлов)
Запустите приложение и проверьте работу

Эта статья помогла вам решить проблему?