#java #android #file #kotlin #file-permissions
#java #Android #файл #kotlin #файл-разрешения
Вопрос:
Я пытаюсь записывать и читать файлы, которые также видны и доступны для редактирования с ПК, когда устройство Android подключено к нему через USB. Эти файлы могут быть созданы через подключение к ПК.
Для достижения этой цели я пытаюсь получить постоянное разрешение URI для каталога, а затем создать или прочитать файлы в этом каталоге.
Я нахожусь на этапе «проверки концепции».
Внутри метода MainActivity onCreate у меня есть следующий код:
startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
}, GET_PERSISTABLE_PERMISSION)
Когда я запускаю приложение, появляется средство выбора каталога, и я могу выбрать каталог.
В MainActivity у меня также есть:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == GET_PERSISTABLE_PERMISSION amp;amp; resultCode == Activity.RESULT_OK) {
val uri = data?.data!!
val contentResolver = applicationContext.contentResolver
val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
contentResolver.takePersistableUriPermission(uri, takeFlags)
val tmpFile = File(uri.path, "debugTestFile.txt")
tmpFile.createNewFile()
tmpFile.appendText("árvíztűrő tükörfúrógéprn")
}
super.onActivityResult(requestCode, resultCode, data)
}
Вещи, которые я пробовал:
uri.toString()
вместоuri.path
flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
при создании намерения- предоставление разных каталогов на устройстве Android в папках Downloads, Music, DCIM при запросе Android
Несмотря на все мои усилия, tmpFile.createNewFile()
строка выдает исключение с сообщением «Нет такого файла или каталога».
Process: hu.ibcs.android.scan, PID: 17309
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.externalstorage.documents/tree/primary:Music/GVtest flg=0xc3 }} to activity {hu.ibcs.android.scan/hu.ibcs.android.scan.MainActivity}: java.io.IOException: No such file or directory
at android.app.ActivityThread.deliverResults(ActivityThread.java:4846)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4887)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7397)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
Caused by: java.io.IOException: No such file or directory
at java.io.UnixFileSystem.createFileExclusively0(Native Method)
at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:317)
at java.io.File.createNewFile(File.java:1008)
at hu.ibcs.android.scan.MainActivity.onActivityResult(MainActivity.kt:106)
at android.app.Activity.dispatchActivityResult(Activity.java:8135)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4839)
Комментарии:
1.
apply { flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
Это не имеет смысла, поскольку вы ничего не можете предоставить, поскольку вы не являетесь поставщиком. Пожалуйста, удалите. Вместо этого вы должны быть рады, что в onActivityResult вы получаете uri и получаете разрешения, которые вы можете использовать постоянно. Ну, вы это делаете.2.
val tmpFile = File(uri.path, "debugTestFile.txt")
Это бессмысленно, поскольку uri.path не является путем файловой системы, и вы не можете использовать для него класс File. Вместо этого вы должны использовать переменную DocumentFile для полученного uri и использовать методы SAF или Storage Access Framework для создания папок и файлов.3.
How do I use a persistable permission that was granted by the Android user?
Вы имеете в виду:How do I use an uri of a file seleced by the Android user?
4. @blackapps Спасибо за помощь! URI относится к каталогу, а не к файлу. Я пытаюсь получить доступ ко всему каталогу и создать / прочитать в нем несколько разных файлов.
Ответ №1:
Большое спасибо @blackapps за предложения!
Я изменил код в MainActivity.onCreate на:
startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), GET_PERSISTABLE_PERMISSION)
и код в MainActivity для:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == GET_PERSISTABLE_PERMISSION amp;amp; resultCode == Activity.RESULT_OK) {
val uri = data?.data!!
val contentResolver = applicationContext.contentResolver
val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
contentResolver.takePersistableUriPermission(uri, takeFlags)
val pickedDir = DocumentFile.fromTreeUri(this, uri)
val tmpFile = pickedDir.createFile("text/csv", "debugTestFile")
val out: OutputStream? = getContentResolver().openOutputStream(tmpFile!!.uri)
out?.write(("uFEFF" "árvíztűrő tükörfúrógéprn").toByteArray()) // adding BOM to the start for Excel to recognize utf8
out?.close()
}
super.onActivityResult(requestCode, resultCode, data)
}
Это работает, и, похоже, я могу двигаться дальше.