'java.io.filenotfoundexception (no such file or directory) while sending image with Retrofit2
Android API 32 (Pixel 5) JetpackCompose 1.1.0 Retrofit 2
I wanna send profile image using WorkManager and Retrofit2 but after choosing image from gallery and send it to UpdateProfilePhotoWorker and creating Mulitpart form data it says
java.io.filenotfoundexception content:\.... (no such file or directory)
but after getting image uri i can load it perfectly
@Composable
fun SelfProfile(navController: NavController, userViewModel: UserViewModel) {
var imageUri by remember {
mutableStateOf<Uri?>(null)
}
val launcher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent()
) { uri: Uri? ->
imageUri = uri
imageUri?.let { userViewModel.setAvatar(it) } // pass to viewmodel to call workmanager
}
Column {
if(imageUri != null) // after selecting image, it shows image!
Image(
painter = rememberImagePainter(data = user_image,
builder = {
transformations(CircleCropTransformation())
}
),
contentDescription = null
)
Button(onClick = { launcher.launch("image/*") } ) {
Text(title="Select Image")
}
}
and here is my viewModel
fun setAvatar(avatar_uri: Uri) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val builder = Data.Builder()
builder.putString("avatar_uri", avatar_uri.toString()) // i need stringify uri to pass it to worker
val revokeTokenRequest = OneTimeWorkRequestBuilder<UpdateProfilePhoto>()
.setConstraints(constraints)
.setInputData(builder.build())
.build()
workManager.beginUniqueWork("SET_AVATAR", ExistingWorkPolicy.KEEP, revokeTokenRequest)
.enqueue()
}
and here is my UpdateProfilePhotoWorker
@HiltWorker
class UpdateProfilePhoto @AssistedInject constructor(
@Assisted appContext: Context,
@Assisted workerParams: WorkerParameters,
private val usersAPI: UsersAPI
) :
CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
return try {
val avatarUriString = inputData.getString("avatar_uri")
val avatarFile = File(avatarUriString)
val response = avatarUriString?.let {
usersAPI.setAvatar(
MultipartBody.Part.createFormData(
"jpg",
"the-f-name",
avatarFile.asRequestBody()
)
)
}
response?.enqueue(object : Callback<String> {
override fun onResponse(
call: Call<String>,
response: Response<String>
) {
Timber.e("Image uploaded")
response.body()?.let {
}
}
override fun onFailure(call: Call<String>, t: Throwable) {
Timber.e("Something went wrong: ${t}")
Result.retry()
}
})
Result.success()
} catch (throwable: Throwable) {
Timber.e(throwable)
Result.retry()
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
