In general, my task is to get base64 from chosen file. In order to open File Browser, I call following function:
private fun showFileBrowser() {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.setType("*/*")
startActivityForResult(intent, FILE_CHOOSE_REQUEST_CODE)
}
It is successfully opened. When some file is chosen, onActivityResult
is called. Here it is:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == FILE_CHOOSE_REQUEST_CODE) {
// not that data.data is Uri
if(data != null && data.data != null) {
val encodedBase64 = getBase64FromPath(data.data.path)
print(encodedBase64)
}
}
}
Here is how I convert File
to base64:
private fun getBase64FromPath(path: String): String {
try {
val bytes = File(path).readBytes()
return Base64.encodeToString(bytes, Base64.DEFAULT)
} catch (error: IOException) {
error.printStackTrace() // This exception always occurs
}
}
Seems like I do everything right, but I get FileNotFoundException
. I don't know what is the reason for this. I didn't add any permission, because I don't to write anything to scared, I just want a user to choose a file, I will convert it to base64 and send it to the server. So, what is the problem this my code?
my task is to get base64 from chosen file
Your code has little to do with files. ACTION_GET_CONTENT
is not limited to files on the device, let alone files on the filesystem that you can access.
When some file is chosen, onActivityResult is called
You get a Uri
via onActivityResult()
. A Uri
is not a file, and getPath()
on a Uri
only has meaning if the scheme of that Uri
is file
. Most Uri
values will have a scheme of content
.
Replace your function with:
private fun getBase64ForUriAndPossiblyCrash(uri: Uri): String {
try {
val bytes = contentResolver.openInputStream(uri).readBytes()
return Base64.encodeToString(bytes, Base64.DEFAULT)
} catch (error: IOException) {
error.printStackTrace() // This exception always occurs
}
The AndPossiblyCrash
portion of the function name is because you are going to run out of memory if the content is too large. Also note that you are doing this work on the main application thread, so your UI will be frozen while you are reading this in.