Storage Access Framework: co to jest, zasady działania i dostęp do plików

Autor: IT Sectr Opublikowano: 2026-07-10 Czas czytania: 6 min

Storage Access Framework — to framework Androida do bezpiecznego dostępu do plików i dokumentów za pomocą systemowego okna wyboru. Zamiast żądania szerokich uprawnień do odczytu pamięci, aplikacja otrzymuje URI-odnośnik do pliku wybranego przez użytkownika. Według Android Developers (2026), SAF obsługuje pamięć lokalną, usługi w chmurze Google Drive i Dropbox przez DocumentProvider. Framework został wprowadzony w Android 4.4 i stał się standardem pracy z dokumentami od Android 10.

Najważniejsze

  • SAF — framework Androida do wyboru plików przez systemowe okno bez szerokich uprawnień.
  • URI-odnośnik zastępuje bezpośrednią ścieżkę pliku: aplikacja pracuje z plikiem przez content URI.
  • Persistent permissions pozwalają zachować dostęp do pliku po ponownym uruchomieniu aplikacji.
  • DocumentProvider rozszerza SAF o dostęp do chmurowych i niestandardowych magazynów.
  • Android 10 uczynił SAF obowiązkowym dla dostępu do plików poza piaskownicą aplikacji.

Czym jest Storage Access Framework?

Storage Access Framework — to część Android SDK, która zapewnia jednolity interfejs do wyboru i tworzenia dokumentów za pomocą systemowego okna dialogowego. SAF abstrahuje fizyczną lokalizację plików: aplikacja nie wie, skąd odczytywany jest plik — z dysku lokalnego, Google Drive czy Dropbox.

Architektura SAF obejmuje trzy komponenty: aplikację kliencką, która inicjuje żądanie, systemowy wybór plików — standardowe okno dialogowe wyboru pliku, oraz DocumentProvider — dostawcę treści implementującego dostęp do plików konkretnego magazynu. Użytkownik widzi jednolity interfejs niezależnie od źródła danych.

SAF jest dostępny od Android 4.4 (API 19). Początkowo framework obsługiwał tylko dokumenty, ale w Android 5.0 dodano obsługę katalogów przez ACTION_OPEN_DOCUMENT_TREE. Od Android 10 SAF stał się zalecanym sposobem dostępu do dowolnego pliku poza app-specific storage.

Jak działa SAF: systemowy wybór plików i URI

SAF uruchamia systemowe okno wyboru pliku przez Intent z akcją ACTION_OPEN_DOCUMENT. Użytkownik widzi listę dostępnych źródeł: pamięć wewnętrzną, Google Drive, Dropbox i innych zarejestrowanych dostawców. Po wybraniu pliku system zwraca content URI z tymczasowymi prawami dostępu.

Content URI ma format content://com.android.externalstorage.documents/document/primary/Download/file.pdf. W przeciwieństwie do file:// URI, content URI nie ujawnia rzeczywistej ścieżki do pliku i działa przez DocumentProvider. Aplikacja odczytuje plik przez ContentResolver.openInputStream na podstawie otrzymanego URI.

Systemowy wybór plików automatycznie obsługuje wyszukiwanie, sortowanie i filtrowanie plików według typów MIME. Deweloper określa potrzebne typy przez Intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/pdf", "image/*")), a wybór plików pokazuje tylko odpowiednie pliki.

Cykl życia URI dostępu

Domyślnie URI jest ważny do ponownego uruchomienia aplikacji lub restartu urządzenia. Długoterminowy dostęp aplikacja uzyskuje przez takePersistableUriPermission — to pozwala odczytywać plik przy kolejnych uruchomieniach bez ponownego wyboru przez okno dialogowe.

ACTION_OPEN_DOCUMENT i ACTION_CREATE_DOCUMENT

SAF udostępnia trzy główne akcje do pracy z plikami: otwieranie, tworzenie i wybór drzewa folderów. ACTION_OPEN_DOCUMENT otwiera systemowy wybór plików do wyboru istniejącego pliku. ACTION_CREATE_DOCUMENT tworzy nowy plik — użytkownik wpisuje nazwę w oknie dialogowym, a aplikacja otrzymuje URI do zapisu.

ACTION_OPEN_DOCUMENT_TREE pozwala wybrać cały katalog i uzyskać dostęp do wszystkich plików w nim. Jest to używane w menedżerach plików, aplikacjach do tworzenia kopii zapasowych i synchronizacji. Aplikacja otrzymuje URI katalogu i może rekurencyjnie przeglądać zawartość przez DocumentFile.

AkcjaPrzeznaczenieFlaga
ACTION_OPEN_DOCUMENTWybór istniejącego plikuREAD_FLAG
ACTION_CREATE_DOCUMENTTworzenie nowego plikuWRITE_FLAG
ACTION_OPEN_DOCUMENT_TREEWybór kataloguREAD + WRITE

Dla każdej akcji określane są typy MIME przez EXTRA_MIME_TYPES. Można podać kilka typów: "application/pdf", "image/*", "text/plain". Jeśli typy nie są określone, wybór plików pokazuje wszystkie pliki.

Persistent URI permissions

Persistent URI permissions — mechanizm SAF, który pozwala zachować dostęp do pliku po zakończeniu bieżącej sesji. Bez tej flagi URI jest ważny tylko do ponownego uruchomienia aplikacji. Aplikacja żąda flagi FLAG_GRANT_PERSISTABLE_URI_PERMISSION wraz z flagami READ i WRITE.

Do zachowania uprawnień używana jest metoda ContentResolver.takePersistableUriPermission. System przechowuje URI w specjalnym rejestrze i przywraca dostęp przy następnym uruchomieniu aplikacji. Aby sprawdzić, czy aplikacja ma trwały dostęp do URI, używana jest ContentResolver.persistedUriPermissions.

Użytkownik może cofnąć zachowane uprawnienia przez Ustawienia → Aplikacje → Uprawnienia. Aplikacja powinna obsługiwać scenariusz, gdy dostęp do pliku niespodziewanie zniknie. Zaleca się sprawdzanie dostępu przez ContentResolver.openInputStream przed rozpoczęciem pracy i prawidłowe obsługiwanie SecurityException.

Przykłady kodu: wybór pliku przez SAF

SAF uruchamiany jest przez standardowy Intent. Kod jest minimalny: utwórz Intent z ACTION_OPEN_DOCUMENT, określ typy MIME i uruchom przez ActivityResultContracts.StartActivityForResult. Po wybraniu pliku callback otrzymuje URI w data.data, który następnie jest używany do odczytu.

kotlin
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)

Tworzenie pliku przez ACTION_CREATE_DOCUMENT

Do zapisu nowego pliku użyj ACTION_CREATE_DOCUMENT. Intent przyjmuje typ MIME i nazwę pliku przez EXTRA_TITLE. Po wybraniu folderu i potwierdzeniu użytkownik zwraca URI, do którego aplikacja zapisuje dane przez ContentResolver.openOutputStream. System automatycznie tworzy plik w wybranej lokalizacji.

SAF vs READ_EXTERNAL_STORAGE

SAF różni się od tradycyjnego READ_EXTERNAL_STORAGE zasadniczo innym podejściem do bezpieczeństwa. Zamiast żądania dostępu do całej pamięci "jednym zamachem", SAF żąda dostępu tylko do konkretnego pliku. Minimalizuje to powierzchnię ataku i zwiększa zaufanie użytkownika.

READ_EXTERNAL_STORAGE daje dostęp do wszystkich plików na urządzeniu, w tym zdjęć i dokumentów innych aplikacji. Na Android 10+ to podejście jest ograniczone. SAF natomiast udostępnia dostęp tylko do wybranego przez użytkownika pliku i wymaga wyraźnego potwierdzenia dla każdego pliku. Do pracy wsadowej z mediami używaj MediaStore, do pojedynczych dokumentów — SAF.

Główną wadą SAF jest konieczność wyboru każdego pliku osobno. Do masowych operacji (kopie zapasowe, synchronizacja folderów) używane jest ACTION_OPEN_DOCUMENT_TREE, który daje dostęp do wszystkich plików w wybranym katalogu. Rozwiązanie zależy od scenariusza: SAF jest optymalny do wyboru przez użytkownika, MediaStore — do programowego dostępu do mediów.

Często zadawane pytania

Czym jest Storage Access Framework w Android?

Storage Access Framework — to framework Androida do bezpiecznego dostępu do plików przez systemowe okno wyboru. Aplikacja otrzymuje content URI do wybranego pliku bez żądania szerokich uprawnień do odczytu pamięci.

Jak otworzyć plik przez SAF?

Utwórz Intent z ACTION_OPEN_DOCUMENT, określ typ MIME przez setType i uruchom przez ActivityResultContracts. W callback otrzymaj URI z data.data i czytaj przez ContentResolver.openInputStream.

Czym są persistent URI permissions?

Persistent URI permissions — to mechanizm zachowania dostępu do URI po ponownym uruchomieniu aplikacji. Żądany przez flagę FLAG_GRANT_PERSISTABLE_URI_PERMISSION i metodę takePersistableUriPermission.

Jakie typy MIME obsługuje SAF?

SAF obsługuje dowolne typy MIME: application/pdf, image/*, text/plain, application/zip i inne. Typy określa się przez Intent.putExtra z tablicą EXTRA_MIME_TYPES.

Czym SAF różni się od MediaStore?

SAF przeznaczony jest do wyboru pojedynczych plików przez użytkownika za pomocą systemowego okna dialogowego. MediaStore zapewnia programowy dostęp do wszystkich plików multimedialnych urządzenia przez bazę multimediów bez udziału użytkownika.

Podsumowanie

  • Storage Access Framework — framework Androida do bezpiecznego dostępu do plików przez systemowy wybór plików bez szerokich uprawnień.
  • Content URI zastępuje ścieżki plików: aplikacja pracuje z plikiem przez DocumentProvider, a nie przez bezpośrednie file:// odnośniki.
  • ACTION_OPEN_DOCUMENT otwiera istniejący plik, ACTION_CREATE_DOCUMENT tworzy nowy, ACTION_OPEN_DOCUMENT_TREE wybiera folder.
  • Persistent permissions zachowują dostęp do URI po ponownym uruchomieniu aplikacji przez takePersistableUriPermission.
  • Android 10 uczynił SAF obowiązkowym dla dostępu do plików poza app-specific storage, ograniczając READ_EXTERNAL_STORAGE.
  • DocumentProvider rozszerza SAF o integrację chmurowych i niestandardowych magazynów.
  • Wybór między SAF a MediaStore zależy od scenariusza: SAF — do wyboru przez użytkownika, MediaStore — do programowego dostępu do mediów.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również