Pek çok güzel soru, hadi araştıralım. :)
Nasıl kullanıyorsun?
KitKat'ta Depolama Erişim Çerçevesi ile etkileşim için harika bir öğretici:
https://developer.android.com/guide/topics/providers/document-provider.html#client
Lollipop'ta yeni API'lerle etkileşim kurmak çok benzer. Kullanıcıdan bir dizin ağacı seçmesini istemek için aşağıdaki gibi bir amaç başlatabilirsiniz:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
Ardından onActivityResult () öğenizde, kullanıcı tarafından seçilen Uri'yi yeni DocumentFile yardımcı sınıfına iletebilirsiniz. İşte seçilen dizindeki dosyaları listeleyen ve ardından yeni bir dosya oluşturan hızlı bir örnek:
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (resultCode == RESULT_OK) {
Uri treeUri = resultData.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
// List all existing files inside picked directory
for (DocumentFile file : pickedDir.listFiles()) {
Log.d(TAG, "Found file " + file.getName() + " with size " + file.length());
}
// Create a new file and write into it
DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
out.write("A long time ago...".getBytes());
out.close();
}
}
Tarafından döndürülen URI DocumentFile.getUri()
, farklı platform API'leri ile kullanılabilecek kadar esnektir. Örneğin, Intent.setData()
ile paylaşabilirsiniz Intent.FLAG_GRANT_READ_URI_PERMISSION
.
Bu Uri'ye yerel koddan erişmek istiyorsanız, çağırabilir ContentResolver.openFileDescriptor()
ve ardından geleneksel bir POSIX dosya tanımlayıcısı tamsayısı elde etmek için ParcelFileDescriptor.getFd()
veya kullanabilirsiniz detachFd()
.
Dosyalara / klasörlere erişip erişemeyeceğinizi nasıl kontrol edersiniz?
Varsayılan olarak, Depolama Erişim Çerçeveleri aracılığıyla döndürülen Uris , yeniden başlatmalarda kalıcı olmaz . Platform, izni sürdürme yeteneği "sunar", ancak isterseniz yine de izni "almanız" gerekir. Yukarıdaki örneğimizde şunu arayacaksınız:
getContentResolver().takePersistableUriPermission(treeUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Uygulamanızın ContentResolver.getPersistedUriPermissions()
API aracılığıyla nelere erişim izni olduğunu her zaman öğrenebilirsiniz . Kalıcı bir URI'ya artık erişmeniz gerekmiyorsa, onu ile serbest bırakabilirsiniz ContentResolver.releasePersistableUriPermission()
.
Bu KitKat'ta mevcut mu?
Hayır, platformun eski sürümlerine geriye dönük olarak yeni işlevler ekleyemiyoruz.
Hangi uygulamaların dosyalara / klasörlere erişimi olduğunu görebilir miyim?
Şu anda bunu gösteren bir kullanıcı arayüzü yoktur, ancak ayrıntıları adb shell dumpsys activity providers
çıktının "Verilen Uri İzinleri" bölümünde bulabilirsiniz .
Bir uygulama aynı cihazda birden çok kullanıcı için yüklenirse ne olur?
Uri izinleri, diğer tüm çok kullanıcılı platform işlevleri gibi, kullanıcı bazında izole edilir. Yani, iki farklı kullanıcı altında çalışan aynı uygulamanın örtüşen veya paylaşılan Uri izin izinleri yoktur.
İzinler iptal edilebilir mi?
Desteklenen DocumentProvider, bulut tabanlı bir belge silindiğinde olduğu gibi herhangi bir zamanda izni iptal edebilir. Bu iptal edilen izinleri keşfetmenin en yaygın yolu, ContentResolver.getPersistedUriPermissions()
yukarıda bahsedilen izinlerin ortadan kalktığı zamandır.
İzin kapsamındaki her iki uygulama için uygulama verileri temizlendiğinde de izinler iptal edilir.
İzin istemek, seçilen bir klasörde yinelemeli olarak çalışır mı?
Evet, ACTION_OPEN_DOCUMENT_TREE
amaç size hem mevcut hem de yeni oluşturulan dosyalara ve dizinlere yinelemeli erişim sağlar.
Bu çoklu seçime izin veriyor mu?
Evet, KitKat'tan bu yana çoklu seçim destekleniyor ve amacınızı EXTRA_ALLOW_MULTIPLE
başlatırken ayarlayarak buna izin verebilirsiniz ACTION_OPEN_DOCUMENT
. Seçilebilecek dosya türlerini daraltmak için Intent.setType()
veya kullanabilirsiniz EXTRA_MIME_TYPES
:
http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT
Öykünücüde yeni API'yi denemenin bir yolu var mı?
Evet, birincil paylaşılan depolama cihazı, öykünücüde bile seçicide görünmelidir. Uygulamanız sadece paylaşılan depolama erişmek için Depolama Erişim Framework kullanıyorsa, artık ihtiyaç READ/WRITE_EXTERNAL_STORAGE
izinleri hiç ve bunları kaldırmak veya kullanabilir android:maxSdkVersion
yalnızca daha eski platformu sürümleri bunları istemek için özelliğini.
Kullanıcı SD kartını bir başkasıyla değiştirdiğinde ne olur?
Fiziksel medya söz konusu olduğunda, temeldeki medyanın UUID'si (FAT seri numarası gibi) her zaman döndürülen Uri'ye yazılır. Sistem, kullanıcı medyayı birden çok yuva arasında değiştirse bile, sizi kullanıcının orijinal olarak seçtiği medyaya bağlamak için kullanır.
Kullanıcı ikinci bir kart takarsa, yeni karta erişim sağlamak için istemeniz gerekir. Sistem, UUID bazında verilen hibeleri hatırladığından, kullanıcı daha sonra yeniden takarsa, orijinal karta önceden erişim izni vermiş olmaya devam edeceksiniz.
http://en.wikipedia.org/wiki/Volume_serial_number