Storage Access Framework — е Android рамка за безопасен достъп до файлове и документи чрез системен диалог за избор. Вместо да иска широки разрешения за четене на хранилище, приложението получава URI връзка към файла, избран от потребителя. Според Android Developers (2026), SAF поддържа локално хранилище, облачни услуги Google Drive и Dropbox чрез DocumentProvider. Рамката е въведена в Android 4.4 и става стандарт за работа с документи от Android 10.
Основни точки
Storage Access Framework — е част от Android SDK, която предоставя унифициран интерфейс за избор и създаване на документи чрез системен диалог. SAF абстрахира физическото местоположение на файловете: приложението не знае откъде се чете файлът — от локалния диск, Google Drive или Dropbox.
Архитектурата на SAF включва три компонента: клиентско приложение, което инициира заявката, системен избирач — стандартен диалог за избор на файл, и DocumentProvider — доставчик на съдържание, който реализира достъп до файловете на конкретно хранилище. Потребителят вижда унифициран интерфейс независимо от източника на данни.
SAF е достъпен от Android 4.4 (API 19). Първоначално рамката поддържаше само документи, но в Android 5.0 беше добавена поддръжка за директории чрез ACTION_OPEN_DOCUMENT_TREE. От Android 10 SAF стана препоръчителният начин за достъп до всеки файл извън app-specific storage.
SAF стартира системен диалог за избор на файл чрез Intent с действие ACTION_OPEN_DOCUMENT. Потребителят вижда списък с налични източници: вътрешна памет, Google Drive, Dropbox и други регистрирани доставчици. След избор на файл, системата връща content URI с временни права за достъп.
Content URI има формат content://com.android.externalstorage.documents/document/primary/Download/file.pdf. За разлика от file:// URI, content URI не разкрива реалния път до файла и работи чрез DocumentProvider. Приложението чете файла чрез ContentResolver.openInputStream на базата на получения URI.
Системният избирач автоматично поддържа търсене, сортиране и филтриране на файлове по MIME типове. Разработчикът задава необходимите типове чрез Intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/pdf", "image/*")), а избирачът показва само релевантни файлове.
По подразбиране URI е валиден до рестартиране на приложението или рестартиране на устройството. За дългосрочен достъп приложението иска takePersistableUriPermission — това позволява четене на файла при следващи стартирания без повторен избор чрез диалог.
SAF предоставя три основни действия за работа с файлове: отваряне, създаване и избор на дърво от папки. ACTION_OPEN_DOCUMENT отваря системния избирач за избор на съществуващ файл. ACTION_CREATE_DOCUMENT създава нов файл — потребителят въвежда име в диалога, а приложението получава URI за запис.
ACTION_OPEN_DOCUMENT_TREE позволява избор на цяла директория и достъп до всички файлове в нея. Използва се във файлови мениджъри, приложения за архивиране и синхронизация. Приложението получава URI на директорията и може рекурсивно да изброява съдържанието чрез DocumentFile.
| Действие | Предназначение | Флаг |
|---|---|---|
| ACTION_OPEN_DOCUMENT | Избор на съществуващ файл | READ_FLAG |
| ACTION_CREATE_DOCUMENT | Създаване на нов файл | WRITE_FLAG |
| ACTION_OPEN_DOCUMENT_TREE | Избор на директория | READ + WRITE |
За всяко действие MIME типовете се задават чрез EXTRA_MIME_TYPES. Могат да бъдат зададени няколко типа: "application/pdf", "image/*", "text/plain". Ако типовете не са зададени, избирачът показва всички файлове.
Persistent URI permissions — SAF механизъм, който позволява запазване на достъпа до файла след приключване на текущата сесия. Без този флаг URI е валиден само до рестартиране на приложението. Приложението иска флага FLAG_GRANT_PERSISTABLE_URI_PERMISSION заедно с READ и WRITE флаговете.
За запазване на правата се използва методът ContentResolver.takePersistableUriPermission. Системата съхранява URI в специален регистър и възстановява достъпа при следващото стартиране на приложението. За да проверите дали приложението има постоянен достъп до URI, се използва ContentResolver.persistedUriPermissions.
Потребителят може да отмени запазените разрешения чрез Настройки → Приложения → Разрешения. Приложението трябва да обработва сценария, когато достъпът до файла неочаквано изчезне. Препоръчва се проверка на достъпа чрез ContentResolver.openInputStream преди започване на работа и правилно обработване на SecurityException.
SAF се стартира чрез стандартен Intent. Кодът е минимален: създайте Intent с ACTION_OPEN_DOCUMENT, задайте MIME типовете и стартирайте чрез ActivityResultContracts.StartActivityForResult. След избор на файл, callback получава URI в data.data, който след това се използва за четене.
val pickFile = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
result.data?.data?.let { uri ->
val inputStream = contentResolver?.openInputStream(uri)
// read from inputStream
}
}
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
setType("application/pdf")
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}
pickFile.launch(intent)
За запис на нов файл използвайте ACTION_CREATE_DOCUMENT. Intent приема MIME типа и името на файла чрез EXTRA_TITLE. След избор на папка и потвърждение, потребителят връща URI, в който приложението записва данни чрез ContentResolver.openOutputStream. Системата автоматично създава файла на избраното място.
SAF се различава от традиционния READ_EXTERNAL_STORAGE с принципно различен подход към сигурността. Вместо да иска достъп до цялото хранилище "наведнъж", SAF иска достъп само до конкретен файл. Това минимизира повърхността за атака и повишава доверието на потребителя.
READ_EXTERNAL_STORAGE дава достъп до всички файлове на устройството, включително снимки и документи на други приложения. На Android 10+ този подход е ограничен. SAF, напротив, предоставя достъп само до файла, избран от потребителя, и изисква изрично потвърждение за всеки файл. За пакетна работа с медии използвайте MediaStore, за отделни документи — SAF.
Основният недостатък на SAF е необходимостта от избор на всеки файл поотделно. За масови операции (архивиране, синхронизация на папки) се използва ACTION_OPEN_DOCUMENT_TREE, който дава достъп до всички файлове в избраната директория. Решението зависи от сценария: SAF е оптимален за избор от потребителя, MediaStore — за програмнен достъп до медии.
Често задавани въпроси
Storage Access Framework — е Android рамка за безопасен достъп до файлове чрез системен диалог за избор. Приложението получава content URI към избрания файл без да иска широки разрешения за четене на хранилище.
Създайте Intent с ACTION_OPEN_DOCUMENT, задайте MIME типа чрез setType и стартирайте чрез ActivityResultContracts. В callback получете URI от data.data и четете чрез ContentResolver.openInputStream.
Persistent URI permissions — е механизъм за запазване на достъпа до URI след рестартиране на приложението. Изисква се чрез флага FLAG_GRANT_PERSISTABLE_URI_PERMISSION и метода takePersistableUriPermission.
SAF поддържа всякакви MIME типове: application/pdf, image/*, text/plain, application/zip и други. Типовете се задават чрез Intent.putExtra с масива EXTRA_MIME_TYPES.
SAF е предназначен за избор на отделни файлове от потребителя чрез системен диалог. MediaStore предоставя програмен достъп до всички медийни файлове на устройството чрез медийната база данни без участие на потребителя.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също