Storage Access Framework, sistem seçim diyaloğu aracılığıyla dosyalara ve belgelere güvenli erişim sağlayan bir Android framework'üdür. Geniş depolama okuma izinleri istemek yerine, uygulama kullanıcının seçtiği dosyaya bir URI bağlantısı alır. Android Developers (2026)'a göre SAF, DocumentProvider aracılığıyla yerel depolama, bulut hizmetleri Google Drive ve Dropbox'ı destekler. Framework, Android 4.4'te tanıtıldı ve Android 10'dan itibaren belgelerle çalışmanın standardı haline geldi.
Önemli Noktalar
Storage Access Framework, sistem diyaloğu aracılığıyla belgeleri seçmek ve oluşturmak için birleşik bir arayüz sağlayan Android SDK'nın bir parçasıdır. SAF, dosyaların fiziksel konumunu soyutlar: uygulama dosyanın nereden okunduğunu bilmez — yerel disk, Google Drive veya Dropbox.
SAF mimarisi üç bileşen içerir: isteği başlatan istemci uygulama, standart bir dosya seçim diyaloğu olan sistem seçici ve belirli bir depolamanın dosyalarına erişimi uygulayan bir içerik sağlayıcı olan DocumentProvider. Kullanıcı, veri kaynağından bağımsız olarak birleşik bir arayüz görür.
SAF, Android 4.4 (API 19)'dan beri kullanılabilir. Başlangıçta framework yalnızca belgeleri destekliyordu, ancak Android 5.0, ACTION_OPEN_DOCUMENT_TREE aracılığıyla dizin desteği ekledi. Android 10'dan itibaren SAF, uygulamaya özel depolama dışındaki herhangi bir dosyaya erişmek için önerilen yöntem haline geldi.
SAF, ACTION_OPEN_DOCUMENT eylemiyle bir Intent aracılığıyla sistem dosya seçim diyaloğunu başlatır. Kullanıcı, mevcut kaynakların bir listesini görür: dahili depolama, Google Drive, Dropbox ve diğer kayıtlı sağlayıcılar. Dosyayı seçtikten sonra, sistem geçici erişim haklarıyla bir content URI döndürür.
Content URI'nin formatı content://com.android.externalstorage.documents/document/primary/Download/file.pdf şeklindedir. file:// URI'sinin aksine, content URI gerçek dosya yolunu açığa çıkarmaz ve DocumentProvider aracılığıyla çalışır. Uygulama, alınan URI'yi kullanarak ContentResolver.openInputStream aracılığıyla dosyayı okur.
Sistem seçici, MIME türlerine göre dosyaların aranması, sıralanması ve filtrelenmesini otomatik olarak destekler. Geliştirici, Intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/pdf", "image/*")) aracılığıyla gerekli türleri belirtir ve seçici yalnızca ilgili dosyaları gösterir.
Varsayılan olarak URI, uygulama yeniden başlatılana veya cihaz yeniden başlatılana kadar geçerlidir. Uzun süreli erişim için uygulama, takePersistableUriPermission talep eder — bu, diyalog aracılığıyla yeniden seçim yapmadan sonraki başlatmalarda dosyayı okumaya izin verir.
SAF, dosyalarla çalışmak için üç ana eylem sağlar: açma, oluşturma ve klasör ağacı seçme. ACTION_OPEN_DOCUMENT, mevcut bir dosyayı seçmek için sistem seçicisini açar. ACTION_CREATE_DOCUMENT yeni bir dosya oluşturur — kullanıcı diyaloga bir ad girer ve uygulama yazmak için bir URI alır.
ACTION_OPEN_DOCUMENT_TREE, tüm bir dizini seçmeye ve içindeki tüm dosyalara erişmeye izin verir. Bu, dosya yöneticilerinde, yedekleme ve senkronizasyon uygulamalarında kullanılır. Uygulama bir dizin URI'si alır ve DocumentFile aracılığıyla içeriği yinelemeli olarak listeleyebilir.
| Eylem | Amaç | Bayrak |
|---|---|---|
| ACTION_OPEN_DOCUMENT | Mevcut dosyayı seç | READ_FLAG |
| ACTION_CREATE_DOCUMENT | Yeni dosya oluştur | WRITE_FLAG |
| ACTION_OPEN_DOCUMENT_TREE | Dizin seç | READ + WRITE |
Her eylem için MIME türleri EXTRA_MIME_TYPES aracılığıyla belirtilir. Birden çok tür belirtilebilir: "application/pdf", "image/*", "text/plain". Hiçbir tür belirtilmezse, seçici tüm dosyaları gösterir.
Persistent URI permissions, geçerli oturum sona erdikten sonra bir dosyaya erişimi korumaya izin veren bir SAF mekanizmasıdır. Bu bayrak olmadan URI, yalnızca uygulama yeniden başlatılana kadar geçerlidir. Uygulama, READ ve WRITE bayraklarıyla birlikte FLAG_GRANT_PERSISTABLE_URI_PERMISSION bayrağını talep eder.
İzinleri kaydetmek için ContentResolver.takePersistableUriPermission yöntemi kullanılır. Sistem, URI'yi özel bir kayıt defterine kaydeder ve bir sonraki uygulama başlatılışında erişimi geri yükler. Uygulamanın bir URI'ye kalıcı erişimi olup olmadığını kontrol etmek için ContentResolver.persistedUriPermissions kullanılır.
Kullanıcı, kaydedilmiş izinleri Ayarlar → Uygulamalar → İzinler aracılığıyla iptal edebilir. Uygulama, bir dosyaya erişimin beklenmedik şekilde kaybolduğu senaryoyu ele almalıdır. Çalışmaya başlamadan önce ContentResolver.openInputStream aracılığıyla erişimi kontrol etmeniz ve SecurityException'ı doğru şekilde işlemeniz önerilir.
SAF, standart bir Intent aracılığıyla başlatılır. Kod minimumdur: ACTION_OPEN_DOCUMENT ile bir Intent oluşturun, MIME türlerini belirtin ve ActivityResultContracts.StartActivityForResult aracılığıyla başlatın. Dosyayı seçtikten sonra, callback data.data içinde URI'yi alır ve bu daha sonra okuma için kullanılır.
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)
Yeni bir dosya yazmak için ACTION_CREATE_DOCUMENT kullanın. Intent, MIME türünü ve EXTRA_TITLE aracılığıyla dosya adını kabul eder. Bir klasör seçip onayladıktan sonra, kullanıcı uygulamanın ContentResolver.openOutputStream aracılığıyla veri yazdığı bir URI döndürür. Sistem, seçilen konumda dosyayı otomatik olarak oluşturur.
SAF, geleneksel READ_EXTERNAL_STORAGE'den güvenliğe temelde farklı bir yaklaşımla ayrılır. Bir kerede tüm depolamaya erişim talep etmek yerine, SAF yalnızca belirli bir dosyaya erişim talep eder. Bu, saldırı yüzeyini en aza indirir ve kullanıcı güvenini artırır.
READ_EXTERNAL_STORAGE, diğer uygulamaların fotoğrafları ve belgeleri dahil olmak üzere cihazdaki tüm dosyalara erişim sağlar. Android 10+'da bu yaklaşım kısıtlanmıştır. SAF ise yalnızca kullanıcının seçtiği dosyaya erişim sağlar ve her dosya için açık onay gerektirir. Toplu medya işlemleri için MediaStore'u kullanın, bireysel belgeler için SAF'i kullanın.
SAF'in ana dezavantajı, her dosyayı ayrı ayrı seçme gerekliliğidir. Toplu işlemler (yedekleme, klasör senkronizasyonu) için, seçilen dizindeki tüm dosyalara erişim sağlayan ACTION_OPEN_DOCUMENT_TREE kullanılır. Çözüm senaryoya bağlıdır: SAF kullanıcı seçimi için idealdir, MediaStore programlı medya erişimi için idealdir.
Sıkça Sorulan Sorular
Storage Access Framework, sistem seçim diyaloğu aracılığıyla güvenli dosya erişimi sağlayan bir Android framework'üdür. Uygulama, geniş depolama okuma izinleri istemeden seçilen dosya için bir content URI alır.
ACTION_OPEN_DOCUMENT ile bir Intent oluşturun, setType ile MIME türünü belirtin ve ActivityResultContracts aracılığıyla başlatın. Callback'te, data.data'dan URI'yi alın ve ContentResolver.openInputStream aracılığıyla okuyun.
Persistent URI permissions, uygulama yeniden başlatıldıktan sonra bir URI'ye erişimi sürdürmek için bir mekanizmadır. FLAG_GRANT_PERSISTABLE_URI_PERMISSION bayrağı ve takePersistableUriPermission yöntemi aracılığıyla talep edilir.
SAF herhangi bir MIME türünü destekler: application/pdf, image/*, text/plain, application/zip ve diğerleri. Türler, EXTRA_MIME_TYPES dizisi ile Intent.putExtra aracılığıyla belirtilir.
SAF, kullanıcının sistem diyaloğu aracılığıyla bireysel dosyaları seçmesi için tasarlanmıştır. MediaStore, kullanıcı müdahalesi olmadan bir medya veritabanı aracılığıyla cihazdaki tüm medya dosyalarına programlı erişim sağlar.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun