1

I'm using file picker to let users decide where to extract specific files. After updating Android API, my app is having problem for getting path of exported file whenever users try to extract file into specific folder via file picker because it returns different uri data from before. When user picks folder where Android system allows, my app creates new file, and copies byte data of specific file into that newly created file.

Copying byte data works fine, but after copying, to notice users that extracting process was successful, I show toast message like Extracted 123.png | Downloads/myPicture/123.png. I just got path by splitting uri path with : letter, but now uri path doesn't contain format like before. Below is how I handle extracting

if(result.resultCode == RESULT_OK) {
    val data = result.data

    if(data != null) {
        val file = current
        val uri = data.data

        if(uri == null || file == null) {
            StaticStore.showShortMessage(this, getString(R.string.file_extract_cant))
        } else {
            val pfd = contentResolver.openFileDescriptor(uri, "w")

            if(pfd != null) {
                val fos = FileOutputStream(pfd.fileDescriptor)
                val ins = file.data.stream

                val b = ByteArray(65536)
                var len: Int

                while(ins.read(b).also { len = it } != -1) {
                    fos.write(b, 0, len)
                }

                ins.close()
                fos.close()

                val path = uri.path

                if(path == null) {
                    StaticStore.showShortMessage(this, getString(R.string.file_extract_semi).replace("_",file.name))
                    return@registerForActivityResult
                }

                val f = File(path)

                val p = f.absolutePath.split(":")[1]

                StaticStore.showShortMessage(this, getString(R.string.file_extract_success).replace("_",file.name).replace("-",p))
            } else {
                StaticStore.showShortMessage(this, getString(R.string.file_extract_cant))
            }
        }
    }
}

Getting extracted file's name isn't problem, but getting path to newly create file is problem. It worked before updating Android API because f.absolutePath returned real path to created file. I can't remember properly what f.absolutePath returned because it's been long time since I made this, but it contained full path next to : letter, so I just splitted text and got path from there. Now f.absolutePath returns document/357 or like this. Number keeps changing (increasing, especially) whenever I try to extract file like document/358, document/359, etc, but it's surely not path where I decided to export. uri itself also returns format like content://com.android.providers.downloads.documents/document/363 as String

Was there any changes for file picker? Is there any way to get full path of created file properly?

Mandarin Smell
  • 391
  • 2
  • 17

1 Answers1

3

You're not supposed to try to get a File's path from a Uri. You just use the Uri itself as your reference to the file's location.

Besides, the user selected the location themselves, so they already know where it is.

Gavin Wright
  • 3,124
  • 3
  • 14
  • 35
  • That actually makes sense. I just wanted to ensure users that file was exported at proper location as users wanted. Well, `uri.path` did returned actual path to file before. If uri wasn't supposed to reveal such path since very first time, I don't know why it contained such data before. Thanks for fast answer by the way, I guess I will just tell users that exporting was successful – Mandarin Smell Aug 24 '21 at 17:05
  • It only contains the data for some devices and in some situations. It's not something you could ever rely on 100%. And now that scoped storage has forced people to use URIs more, they're discovering this. – Gavin Wright Aug 24 '21 at 20:00