'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