Dosya yolu vs URI: Android'de content:// ve file:// için pratik inceleme
Kısa cevap: content:// — ContentProvider üzerinden erişim (InputStream/OutputStream ile çalışın), file:// — dosya sisteminde doğrudan yol ve yalnızca kendi dosyalarınız için uygundur; çoğu zaman content:// için "gerçek" bir yol yoktur, bu nedenle akışlar üzerinden okumanız veya dosyayı kendi depolama alanınıza kopyalamanız gerekir.
content:// ve file:// arasındaki farklar
- file:// — gerçek bir dosyayı gösterir, örneğin /data/data/
/files/image.jpg. Oluşturduğunuz ve kontrol ettiğiniz dosyalar için uygundur. java.io.File kullanılabilir. - content:// — ContentProvider üzerinden soyutlama (galeri, SAF, diğer uygulamalar). URI gerçek yolu açığa çıkarmaz; erişim ContentResolver (openInputStream/openOutputStream) ve belge API'leri aracılığıyla sağlanır.
content:// adreslerini toplu olarak /storage/… formatına dönüştürmeye çalışmayın — modern Android'de bu, scoped storage ve bulut sağlayıcıları nedeniyle güvenilir değildir ve çoğu zaman imkansızdır.
Yalnızca content:// varsa ne yapmalı — pratik rehber
- Akışı açın:
- InputStream in = context.getContentResolver().openInputStream(uri)
- Yalnızca okumak/görüntülemek istiyorsanız — akışla doğrudan çalışın (BitmapFactory, ayrıştırıcılar, sunucuya yükleme).
- Bir kütüphane "dosya yolu" gerektiriyorsa veya kalıcı erişime ihtiyacınız varsa — verileri kendi alanınızdaki bir dosyaya kopyalayın:
- gerekirse context.getFilesDir() veya context.getCacheDir() ya da externalFilesDir(...) içinde bir dosya oluşturun;
- OutputStream out = new FileOutputStream(destFile);
- verileri in'den out'a bayt bayt kopyalayın, akışları kapatın.
- Yolu/URI'yi size en uygun şekilde saklayın: dahili işlemler için kendi kopyanızın yolunu saklayın; kaynak bağlantısı için orijinal content:// adresini saklayın.
Üçüncü taraf bir kütüphane "gerçek yol" gerektiriyorsa, content:// adresini geçici bir dosyaya kopyalayın ve kopyanın yolunu iletin. Bu basit ve güvenilir bir çözümdür.
Uygulama içinde dosyaları doğru şekilde oluşturma ve saklama
- Dahili depolama (izin gerektirmez): context.filesDir — yalnızca uygulama tarafından erişilebilen kararlı yol.
- Kapsamlı harici depolama (Android/data/
/files): context.getExternalFilesDir(...) — büyük dosyalar için uygundur, kullanıcı tarafından dosya gezgini aracılığıyla sınırlı olarak görülebilir. - Geçici görevler için context.getCacheDir() veya File.createTempFile(..., context.cacheDir) kullanın.
Algoritma:
- Dizin seçin (filesDir / cacheDir / externalFilesDir).
- API aracılığıyla dosya oluşturun (File(...) veya openFileOutput).
- Akışlar aracılığıyla yazma/okuma yapın ve geçici dosyaların doğru şekilde silinmesini sağlayın.
Sık yapılan hatalar
- content:// adresinin her zaman /storage/… formatına dönüştürülebileceğini beklemek — arızalara neden olur.
- FileProvider olmadan başka bir uygulamaya file:// adresi iletmek — yeni Android sürümlerinde FileUriExposedException hatasına neden olur.
- Kopyalama sırasında büyük dosyaları bellekte tutmak — arabellek (örneğin 8 KB) ve akışlar kullanın.
- Akışları kapatmamak — sızıntılara ve dosya bozulmasına neden olur.
SSS
-
content:// adresinden gerçek yol alınabilir mi?
Bazen mümkündür (eski cihazlarda veya belirli sağlayıcılar için), ancak genel olarak buna güvenilmemelidir. ContentResolver ve kopyalama yöntemiyle çalışmak daha iyidir. -
Başka bir uygulamayla dosya nasıl güvenli şekilde paylaşılır?
FileProvider kullanın ve grantUriPermission ile veya FLAG_GRANT_READ_URI_PERMISSION / FLAG_GRANT_WRITE_URI_PERMISSION bayraklarına sahip Intent ile geçici URI'ler (content://) verin. -
Kütüphane yalnızca File kabul ediyor ve InputStream desteklemiyorsa ne yapılmalı?
İçeriği kendi alanınızdaki bir dosyaya kopyalayın ve bu kopyanın yolunu iletin. -
Harici depolamayı okuma izni istemek gerekir mi?
Kendi dizinlerinize erişim için gerek yoktur. Eski sürümlerde herkese açık dosyalara erişim için READ_EXTERNAL_STORAGE gerekebilir; modern Android için SAF veya scoped storage kullanın.
Temel strateji olarak akış tabanlı erişimi ve kendi depolama alanınıza kopyalamayı kullanın: bu, Android güvenlik politikalarıyla uyumludur ve farklı cihazlar ve işletim sistemi sürümlerinde kararlı davranış sağlar.