DocumentFile ve Storage Access Framework ile Çalışma

Kerem Aydın·8 Temmuz 2026·⏱2 dk

SAF (Storage Access Framework), uygulamanıza kullanıcının seçtiği dosya ve klasörlere Uri üzerinden erişim sağlar; DocumentFile ise bu Uri'ler üzerinde CRUD işlemleri gerçekleştirmek için kullanışlı bir sarmalayıcıdır. Erişimin oturumlar arasında korunması için takePersistableUriPermission çağrısı yapmak ve Uri'nin dize gösterimini saklamak şarttır.

Neden gereklidir ve ne zaman kullanılmalıdır

  • Android 11+ (Scoped Storage) üzerinde getExternalFilesDir() dışındaki dosyalara erişim gerektiğinde.
  • Dosya yöneticileri, düzenleyiciler, yedekleme ve içe/dışa aktarma işlemleri için.
  • Uygulamanın kendi klasöründe çalışmak yeterliyse gerekli değildir.

Proje kurulumu ve temel akış

  1. Bağımlılığı ekleyin:
implementation "androidx.documentfile:documentfile:1.0.1"
implementation "androidx.activity:activity-ktx:1.9.2"
  1. Sistem seçiciyi başlatın ve izinleri kalıcı olarak kaydedin:
  • Önerilen yöntem: Activity Result API.

Klasör seçimi örneği (ActivityResultLauncher):

val openFolderLauncher = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
    if (uri != null) {
        contentResolver.takePersistableUriPermission(uri,
            Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
        prefs.edit().putString("tree_uri", uri.toString()).apply()
        // DocumentFile.fromTreeUri(context, uri) — bundan sonra bununla çalışıyoruz
    }
}

Kaydedilmiş Uri'yi yükleme:

fun loadTreeUri(): Uri? = prefs.getString("tree_uri", null)?.let { Uri.parse(it) }

DocumentFile ile temel işlemler

  • Kökü elde etme: val root = DocumentFile.fromTreeUri(context, treeUri)!!
  • Listeleme: root.listFiles()
  • Klasör oluşturma: root.createDirectory("MyFolder")
  • Dosya oluşturma: folder.createFile("text/plain", "note.txt")
  • Okuma: contentResolver.openInputStream(file.uri)?.use { it.reader().readText() }
  • Yazma: contentResolver.openOutputStream(file.uri)?.use { it.write(bytes) }
  • Silme: file.delete()

Hızlı başlangıç: OpenDocumentTree'ü çağırın ve hemen takePersistableUriPermission ile izinleri kaydedin — bu, çoğu görev için yeterlidir.

Tablo: DocumentFile ve File API karşılaştırması

NeDocumentFile (SAF)File API
Harici dosyalara erişimKullanıcı seçimine göre (Uri)İzinler aracılığıyla (sınırlı)
Android 11+ uyumluluğuEvetYalnızca dahili klasör
Erişimi korumatakePersistableUriPermissionRuntime izinleri aracılığıyla
Kullanım kolaylığıUri ile çalışma, ContentResolver gerekirDoğrudan yollar, daha basit API

documentFile.length() üzerinden doğru dosya boyutuna güvenmeyin — SAF bazı sağlayıcılarda 0 veya yanlış değerler döndürür. Gerçek boyutu kontrol etmek için openInputStream kullanın.

Yaygın hatalar

  • takePersistableUriPermission çağrılmaması — yeniden başlatma sonrası erişim kaybolur.
  • Activity Result API yerine deprecated startActivityForResult kullanılması.
  • Geçersiz bir Uri'den DocumentFile oluşturulmaya çalışılması (null kontrolü yapın).
  • File API davranışı beklenmesi (yollar, erişimler, kilitlemeler).

SSS

  • READ_EXTERNAL_STORAGE istemek gerekir mi? Hayır — SAF aracılığıyla seçilen kaynaklar için bu gerekli değildir.
  • Farklı sağlayıcıların treeUri'leri arasında dosya kopyalanabilir mi? Evet, ancak hedef Uri'de InputStream ile okuyup OutputStream ile yazmanız gerekir.
  • Erişim nasıl iptal edilir? Kaydedilmiş Uri'yi prefs'ten silin ve kullanıcıdan sistem erişim yönetimi ayarlarından erişimi kaldırmasını isteyin.

Kullanıcı gizliliğine saygı duymak ve Scoped Storage ile uyumluluk sağlamak gerektiğinde SAF + DocumentFile kullanın — modern Android'de harici dosyalarla çalışmanın tek güvenilir yolu budur.