Android 11 ACTION_OPEN_DOCUMENT_TREE: Anfangs-URI auf den Ordner „Dokumente“ setzen [duplicate]
Lesezeit: 5 Minuten
Kenobi
Mit dem Scoped Storage-Modell in Android 11 möchte ich dem Benutzer die Möglichkeit geben, einen Ordner auszuwählen, beginnend im Dokumentenordner:
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, ??? )
startActivityForResult(intent, OPEN_DIRECTORY_REQUEST_CODE,null)
Das Problem ist, wie kann ich eine korrekte URI des Dokumentenordners des Telefons generieren? (Es befindet sich nur in root / ) In der offiziellen Dokumentation werden keine Beispiele angegeben. Ich hoffe wirklich, dass es einige nette Konstanten für alle Standardstandorte gibt?
“Das Problem ist, wie kann ich eine korrekte URI des Dokumentenordners des Telefons generieren?” – AFAIK, dafür gibt es keine Option, sorry. EXTRA_INITIAL_URI ist so konzipiert, einige zu sein Uri von denen Sie zuvor bezogen haben ACTION_OPEN_DOCUMENT_TREE.
– CommonsWare
15. Mai 2021 um 23:44 Uhr
@CommonsWare, bitte schau dir meine Antwort an.
– Blackapps
16. Mai 2021 um 8:51 Uhr
schwarze Apps
Wir werden manipulieren INITIAL_URI erhalten von StorageManager..getPrimaryStorageVolume().createOpenDocumentTreeIntent().
Sie machen Annahmen über die Uri Format; Diese Annahmen sind möglicherweise nicht über Android-Versionen hinweg stabil.
– CommonsWare
16. Mai 2021 um 10:25 Uhr
Vielen Dank, das werde ich ausprobieren. Es ist gut genug, wenn es für die meisten Telefone funktioniert, solange es auf den anderen nicht abstürzt. Es ist der “besser als nichts”-Ansatz.
– Kenobi
16. Mai 2021 um 11:36 Uhr
Funktioniert dies in Android-9 und niedrigeren Versionen?
– K Pradeep Kumar Reddy
18. Mai 2021 um 5:12 Uhr
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q)
– Blackapps
18. Mai 2021 um 6:52 Uhr
Hoffentlich wird das Android-Team dies mit einer Standardimplementierung in einer zukünftigen Android-Version beheben, wenn die obige Lösung kaputt geht.
– Benutzer1608385
18. August 2021 um 15:35 Uhr
verrückter_junge
Wie kann ich eine korrekte URI des Dokumentenordners des Telefons generieren?
Getestet am:
Xiaomi M2102J20SI
Emulator Pixel 4 XL API 30
Funktion askPermission() öffnet das Zielverzeichnis.
@RequiresApi(Build.VERSION_CODES.Q)
private fun askPermission() {
val storageManager = application.getSystemService(Context.STORAGE_SERVICE) as StorageManager
val intent = storageManager.primaryStorageVolume.createOpenDocumentTreeIntent()
val targetDirectory = "WhatsApp%2FMedia%2F.Statuses" // add your directory to be selected by the user
var uri = intent.getParcelableExtra<Uri>("android.provider.extra.INITIAL_URI") as Uri
var scheme = uri.toString()
scheme = scheme.replace("/root/", "/document/")
scheme += "%3A$targetDirectory"
uri = Uri.parse(scheme)
intent.putExtra("android.provider.extra.INITIAL_URI", uri)
startActivityForResult(intent, REQUEST_CODE)
}
Uri der Datei wird zurückgegeben onActivityResult()
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data != null) {
data.data?.let { treeUri ->
// treeUri is the Uri of the file
// if life long access is required the takePersistableUriPermission() is used
contentResolver.takePersistableUriPermission(
treeUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
)
readSDK30(treeUri)
}
}
}
}
Funktion readSDK30() wird zum Lesen von Dateien und Ordnern verwendet Uri
private fun readSDK30(treeUri: Uri) {
val tree = DocumentFile.fromTreeUri(this, treeUri)!!
thread {
val uriList = arrayListOf<Uri>()
listFiles(tree).forEach { uri ->
// Collect all the Uri from here
}
}
}
Funktion listFiles() gibt alle Dateien und Ordner in der angegebenen zurück Uri
fun listFiles(folder: DocumentFile): List<Uri> {
return if (folder.isDirectory) {
folder.listFiles().mapNotNull { file ->
if (file.name != null) file.uri else null
}
} else {
emptyList()
}
}
Danke, das sagt im Grunde, wie man Scoped Storage für ein zufälliges Startverzeichnis verwendet. Danke für den sauberen Code. Meine Frage war leider, wie man Scoped Storage für ein FIXED Startverzeichnis nutzt, das der User nicht selbst wählen darf.
– Kenobi
16. Mai 2021 um 11:31 Uhr
@Kenobi, wie man ACTION_OPEN_DOCUMENT_TREE verwendet…….. Es hat nichts mit bereichsbezogener Speicherung zu tun …
– Blackapps
18. Mai 2021 um 6:42 Uhr
Wie können wir Eigenschaften wie Dauer, Auflösung (wenn es sich bei der Datei um ein Video handelt) aus dem documentfile-Objekt abrufen?
– Himanshu
22. Januar um 11:01 Uhr
Kenobi
Der gesamte Verdienst geht an die obige Antwort von @blackapp!
Hier ist der gleiche Code in Kotlin-Sprache:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
val sm = getSystemService(Context.STORAGE_SERVICE) as StorageManager
intent = sm.primaryStorageVolume.createOpenDocumentTreeIntent()
//String startDir = "Android";
//String startDir = "Download"; // Not choosable on an Android 11 device
//String startDir = "DCIM";
//String startDir = "DCIM/Camera"; // replace "/", "%2F"
//String startDir = "DCIM%2FCamera";
val startDir = "Documents"
var uriroot = intent.getParcelableExtra<Uri>("android.provider.extra.INITIAL_URI") // get system root uri
var scheme = uriroot.toString()
Log.d("Debug", "INITIAL_URI scheme: $scheme")
scheme = scheme.replace("/root/", "/document/")
scheme += "%3A$startDir" //change uri to Documents folder
uriroot = Uri.parse(scheme)
intent.putExtra("android.provider.extra.INITIAL_URI", uriroot) // give changed uri to Intent
Log.d("Debug", "uri: $uriroot")
startActivityForResult(intent, OPEN_DIRECTORY_REQUEST_CODE);
}
Wie einige Kommentatoren erwähnt haben, könnte dieser Code brechen und in Zukunft nicht mehr funktionieren, was wahr ist. In Anbetracht der Vergangenheit von Android werden sie die Speicher-API jedoch sowieso alle zwei Jahre ändern.
Bitte posten Sie Ihren Kotlin-Code erneut an dem oben genannten Posten ‘Frage hat hier bereits eine Antwort: ‘ Besucher dieser Seite hier werden nicht weiter suchen, also denke ich, dass Ihr Code dort besser ist.
– Blackapps
28. Mai 2021 um 10:26 Uhr
10140600cookie-checkAndroid 11 ACTION_OPEN_DOCUMENT_TREE: Anfangs-URI auf den Ordner „Dokumente“ setzen [duplicate]yes
“Das Problem ist, wie kann ich eine korrekte URI des Dokumentenordners des Telefons generieren?” – AFAIK, dafür gibt es keine Option, sorry.
EXTRA_INITIAL_URI
ist so konzipiert, einige zu seinUri
von denen Sie zuvor bezogen habenACTION_OPEN_DOCUMENT_TREE
.– CommonsWare
15. Mai 2021 um 23:44 Uhr
@CommonsWare, bitte schau dir meine Antwort an.
– Blackapps
16. Mai 2021 um 8:51 Uhr