i am trying to select an image from my gallery and then uploading to my server with a form-data request
this is how i start intent to select image
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE)
and this is my onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode == SELECT_PICTURE && resultCode == RESULT_OK && data != null) {
true -> {
data.data?.let {
teamImagePlaceholder?.setImageURI(it)
it.path?.let { path ->
selectedImage = File(path)
selectedImage?.createNewFile()
}
}
}
}
}
the app then crashes at the line selectedImage?.createNewFile() and this is the stacktrace
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=66036, result=-1, data=Intent { dat=content://com.android.providers.downloads.documents/document/raw:/storage/emulated/0/Download/download.jpeg flg=0x1 }} to activity {.MainActivity}: java.io.IOException: No such file or directory
at android.app.ActivityThread.deliverResults(ActivityThread.java:4845)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4886)
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:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
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:930)
Caused by: java.io.IOException: No such file or directory
and this is the retrofit method where i make the api call
fun createNewTeam(teamName: String, teamTarget: String, teamDescription: String, teamImage: String?,
successCallback: (CreateTeamResponse?) -> Unit, failureCallback: () -> Unit) {
val name = MultipartBody.Part.createFormData("team_name", null, RequestBody.create(MediaType.parse("text/plain"), teamName))
val target = MultipartBody.Part.createFormData("team_target", null, RequestBody.create(MediaType.parse("text/plain"), teamTarget))
val description = MultipartBody.Part.createFormData("team_description", null, RequestBody.create(MediaType.parse("text/plain"), teamDescription))
val image = when (teamImage) {
null -> MultipartBody.Part.createFormData("team_image", "")
else -> MultipartBody.Part.createFormData("team_image", teamImage, RequestBody.create(MediaType.parse("image/*"), teamImage))
}
client.createNewTeam(name, target, description, image).enqueue(object : Callback<CreateTeamResponse> {
override fun onResponse(call: Call<CreateTeamResponse>, response: Response<CreateTeamResponse>) {
successCallback(response.body())
}
override fun onFailure(call: Call<CreateTeamResponse>, t: Throwable) {
failureCallback()
}
})
}
retrofit interface
@Multipart
@POST("api/apihere")
fun createNewTeam(@Part teamName: MultipartBody.Part, @Part teamTarget: MultipartBody.Part,
@Part teamDescription: MultipartBody.Part, @Part teamImage: MultipartBody.Part): Call<CreateTeamResponse>
EDIT
after following CommonWares answer on the other question this is my code now
repo
fun createNewTeam(teamName: String, teamTarget: String, teamDescription: String, teamImage: Uri?,
contentResolver: ContentResolver, successCallback: (CreateTeamResponse?) -> Unit, failureCallback: () -> Unit) {
val builder = MultipartBody.Builder()
builder.addFormDataPart("team_name", null, RequestBody.create(MediaType.parse("text/plain"), teamName))
builder.addFormDataPart("team_target", null, RequestBody.create(MediaType.parse("text/plain"), teamTarget))
builder.addFormDataPart("team_description", null, RequestBody.create(MediaType.parse("text/plain"), teamDescription))
if(teamImage != null)
builder.addFormDataPart("team_image", teamImage.toString(), InputStreamRequestBody(MediaType.parse("image/*")!!, contentResolver, teamImage))
builder.setType(MultipartBody.FORM)
val requestBody = builder.build()
client.createNewTeam(requestBody).enqueue(object : Callback<CreateTeamResponse> {
override fun onResponse(call: Call<CreateTeamResponse>, response: Response<CreateTeamResponse>) {
successCallback(response.body())
}
override fun onFailure(call: Call<CreateTeamResponse>, t: Throwable) {
failureCallback()
}
})
}
interface
@POST("api/apihere")
fun createNewTeam(@Body multipartBody: MultipartBody): Call<CreateTeamResponse>
i am still getting the same issue, request succeeds but the image is never uploaded