Kotlin,我如何对从 OnActivityResult 返回的文件进行 base64Encode
Kotlin, how can I base64Encode the file I get back from the OnActivityResult
我需要制定向电子邮件客户端添加附件的逻辑。
我拥有所有需要的权限,并为文件创建了一个意图:
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
activity?.startActivityForResult(intent, ActivityResultHandler.PICK_FILE)
我选择了一个文件,并且在我的 onActivityResult 中得到了正确的结果:
public override fun onActivityResult(reqCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(reqCode, resultCode, data)
ActivityResultHandler().onActivityResult(this, reqCode, resultCode, data)
if (reqCode == REQUEST_CODE_SET_DEFAULT_DIALER) {
activityToFragmentCommunicationCallback?.sendData("refresh")
} else if (reqCode == ActivityResultHandler.PICK_FILE && resultCode == RESULT_OK && data != null) {
val uri = data.data
val cr = this.contentResolver
val mime = cr.getType(uri)
var file = uri.toFile()
if (file.exists()) {
var base64 = convertToBase64(file)
DialogFullScreenEmailComposer.addAttachment()
}
}
}
但随后它崩溃了:var file = uri.toFile()
告诉我:
2019-09-18 16:12:12.300 20608-20608/com.xelion.android.debug E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xelion.android.debug, PID: 20608
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=3, result=-1, data=Intent { dat=content://com.android.providers.downloads.documents/document/raw:/storage/emulated/0/Download/106.apk flg=0x1 }} to activity {com.xelion.android.debug/com.xelion.android.activity.MainActivity}: java.lang.IllegalArgumentException: Uri lacks 'file' scheme: content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2F106.apk
at android.app.ActivityThread.deliverResults(ActivityThread.java:4398)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4440)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalArgumentException: Uri lacks 'file' scheme: content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2F106.apk
at androidx.core.net.UriKt.toFile(Uri.kt:40)
at com.xelion.android.activity.MainActivity.onActivityResult(MainActivity.kt:312)
at android.app.Activity.dispatchActivityResult(Activity.java:7462)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4391)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4440)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
如何才能创建我的文件?或者我可以跳过它并直接创建 base64Encoded 吗?
错误消息表明 Uri
没有指向文件(它不是以 file://
开头)。在较新的 Android 版本中,您无法直接访问您请求的文件,但您可以通过 ContentResolver
读取其内容。您可以通过使用 cr.openInputStream(uri)
打开 InputStream
来做到这一点。当你拥有它时,你可以从该流中读取并将结果转换为 Base64。
下面是一个关于如何将文件的全部内容读入 ByteArray 的示例:
private fun readFile(cr: ContentResolver, uri: Uri): ByteArray {
val inStream = cr.openInputStream(uri) ?: return ByteArray(0)
val outStream = ByteArrayOutputStream()
val buffer = ByteArray(32)
while (inStream.read(buffer) > 0) {
outStream.write(buffer)
}
return outStream.toByteArray()
}
我需要制定向电子邮件客户端添加附件的逻辑。 我拥有所有需要的权限,并为文件创建了一个意图:
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
activity?.startActivityForResult(intent, ActivityResultHandler.PICK_FILE)
我选择了一个文件,并且在我的 onActivityResult 中得到了正确的结果:
public override fun onActivityResult(reqCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(reqCode, resultCode, data)
ActivityResultHandler().onActivityResult(this, reqCode, resultCode, data)
if (reqCode == REQUEST_CODE_SET_DEFAULT_DIALER) {
activityToFragmentCommunicationCallback?.sendData("refresh")
} else if (reqCode == ActivityResultHandler.PICK_FILE && resultCode == RESULT_OK && data != null) {
val uri = data.data
val cr = this.contentResolver
val mime = cr.getType(uri)
var file = uri.toFile()
if (file.exists()) {
var base64 = convertToBase64(file)
DialogFullScreenEmailComposer.addAttachment()
}
}
}
但随后它崩溃了:var file = uri.toFile()
告诉我:
2019-09-18 16:12:12.300 20608-20608/com.xelion.android.debug E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xelion.android.debug, PID: 20608
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=3, result=-1, data=Intent { dat=content://com.android.providers.downloads.documents/document/raw:/storage/emulated/0/Download/106.apk flg=0x1 }} to activity {com.xelion.android.debug/com.xelion.android.activity.MainActivity}: java.lang.IllegalArgumentException: Uri lacks 'file' scheme: content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2F106.apk
at android.app.ActivityThread.deliverResults(ActivityThread.java:4398)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4440)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalArgumentException: Uri lacks 'file' scheme: content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2F106.apk
at androidx.core.net.UriKt.toFile(Uri.kt:40)
at com.xelion.android.activity.MainActivity.onActivityResult(MainActivity.kt:312)
at android.app.Activity.dispatchActivityResult(Activity.java:7462)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4391)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4440)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
如何才能创建我的文件?或者我可以跳过它并直接创建 base64Encoded 吗?
错误消息表明 Uri
没有指向文件(它不是以 file://
开头)。在较新的 Android 版本中,您无法直接访问您请求的文件,但您可以通过 ContentResolver
读取其内容。您可以通过使用 cr.openInputStream(uri)
打开 InputStream
来做到这一点。当你拥有它时,你可以从该流中读取并将结果转换为 Base64。
下面是一个关于如何将文件的全部内容读入 ByteArray 的示例:
private fun readFile(cr: ContentResolver, uri: Uri): ByteArray {
val inStream = cr.openInputStream(uri) ?: return ByteArray(0)
val outStream = ByteArrayOutputStream()
val buffer = ByteArray(32)
while (inStream.read(buffer) > 0) {
outStream.write(buffer)
}
return outStream.toByteArray()
}