Wavesonics / compose-multiplatform-file-picker

A multiplatform compose widget for picking files
MIT License
345 stars 21 forks source link

Issue fetching files on Android #129

Open N7ghtm4r3 opened 6 months ago

N7ghtm4r3 commented 6 months ago

Hi using the latest version of the multiple file picker (3.1.0) using the following snippet of code:

MultipleFilePicker(
    show = //showFilePicker,
    fileExtensions = //file extensions
) { assets ->
    if(!assets.isNullOrEmpty()) {
        val assetsPath = mutableListOf<File>()
        assets.forEach { asset ->
            assetsPath.add(File(asset.path))
        }
        if(assetsPath.isNotEmpty()) {
            // do code
        }
    }
}

will be thrown the following exception: Caused by: java.io.FileNotFoundException: /document/msf:59701: open failed: ENOENT (No such file or directory).

There is a way to get directly the file from the Android's storage? Because using the asset.path it looks like does not get the complete path to get the file

JagadishaIncture commented 5 months ago

any workaround. Iam also facing same issue. Desktop its working fine but Android its failing

N7ghtm4r3 commented 5 months ago

I used this function to get the path where Android store the file

fun getFilePath(
    context: Context,
    uri: Uri
): String? {
    val returnCursor = context.contentResolver.query(uri, null, null, null, null)
    val nameIndex =  returnCursor!!.getColumnIndex(OpenableColumns.DISPLAY_NAME)
    val sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE)
    returnCursor.moveToFirst()
    val name = returnCursor.getString(nameIndex)
    returnCursor.getLong(sizeIndex).toString()
    val file = File(context.filesDir, name)
    try {
        val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
        val outputStream = FileOutputStream(file)
        var read = 0
        val maxBufferSize = 1 * 1024 * 1024
        val bytesAvailable: Int = inputStream?.available() ?: 0
        val bufferSize = min(bytesAvailable, maxBufferSize)
        val buffers = ByteArray(bufferSize)
        while (inputStream?.read(buffers).also {
                if (it != null) {
                    read = it
                }
            } != -1) {
            outputStream.write(buffers, 0, read)
        }
        inputStream?.close()
        outputStream.close()
    } catch (_: Exception) {
    } finally {
        returnCursor.close()
    }
    return file.path
}

For the uri you can use the FilePicker and the result path or you can take a look here to implement the built-in solution

JagadishaIncture commented 5 months ago

it worked Thanks.

N7ghtm4r3 commented 5 months ago

I'm happy about this!