简体   繁体   English

当我只有一个目录的 uri 时,如何创建文件? (该目录的持久权限由 Android 用户授予。)

[英]How do I create files when all I have is an uri of a directory? (Persistable permission for the directory was granted by the Android user.)

I am trying to write and read files that are also visible and editable from a PC when the android device is connected to it via USB.我正在尝试写入和读取在 android 设备通过 USB 连接到 PC 时也可以从 PC 上看到和编辑的文件。 These files might be created through the PC connection.这些文件可能是通过 PC 连接创建的。

To achieve this I'm trying to take a persistable URI permission to a directory, and then create or read the files in that directory.为了实现这一点,我正在尝试获取对目录的持久 URI 权限,然后在该目录中创建或读取文件。

I am in the "proof of concept" phase.我正处于“概念验证”阶段。

Inside the MainActivity OnCreate method I have the following code:在 MainActivity OnCreate 方法中,我有以下代码:

startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
    flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
}, GET_PERSISTABLE_PERMISSION)

When I start te app, the directory picker pops up and I'm able to select a directory.当我启动 te 应用程序时,目录选择器会弹出,我可以选择一个目录。

In MainActivity I also have:在 MainActivity 我也有:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == GET_PERSISTABLE_PERMISSION && 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ép\r\n")
    }
    super.onActivityResult(requestCode, resultCode, data)
}

Things I've tried:我尝试过的事情:

  • uri.toString() instead of uri.path 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 when creating the intent创建意图时, flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
  • giving different directories on the Android device in the Downloads, Music, DCIM folders, when prompted by Android当 Android 提示时,在下载、音乐、DCIM 文件夹中为 Android 设备提供不同的目录

Despite my best efforts, the tmpFile.createNewFile() line throws an exception with "No such file or directory" message.尽管我尽了最大的努力,但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)

Big thanks to @blackapps for the suggestions!非常感谢@blackapps 的建议!

I changed the code in MainActivity.onCreate to:我将 MainActivity.onCreate 中的代码更改为:

startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), GET_PERSISTABLE_PERMISSION)

and the code in MainActivity to:和 MainActivity 中的代码:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == GET_PERSISTABLE_PERMISSION && 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ép\r\n").toByteArray()) // adding BOM to the start for Excel to recognize utf8
        out?.close()
    }
    super.onActivityResult(requestCode, resultCode, data)
}

It's working and it looks like I can move on from here.它正在工作,看起来我可以从这里继续前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM