NewPartizal
NewPartizal

Reputation: 1104

Why my imageUri change when I pass as a argument to another screen in jetpack compose?

I have a screen to select a photo from the gallery, and on this screen, I select the photo from the gallery and transfer the imageUri I selected to the screen I want to display. So, we can think of it as the previous screen, but there is a difference between the imageUri I selected and the imageUri I passed. My codes are as follows

this is my choose image from gallery screen

@Composable
fun CNChooseImageScreen(
    navHostController: NavHostController
) {

    var imageUri by remember { mutableStateOf<Uri>(Uri.EMPTY) }

    val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.GetContent()
    ) { uri: Uri? ->

        if (uri != null) {
            imageUri = uri
        }else{
            //if occurs error
            navHostController.navigate(HealthScreen.HealthCreateNutritionScreen.route)
        }
    }

    LaunchedEffect(Unit) {
        launcher.launch("image/*")
    }

    var doOnce by remember{ mutableStateOf(true) }

    if (imageUri.path?.isNotEmpty() == true && doOnce) {

        println("choose "+imageUri)
        navHostController.navigate("${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO=$imageUri ")

        doOnce = false
    }
}

CreateNutritionRoute ViewModel

I receive the image Url that I sent in the viewmodel of the screen I want to display.

init {
        val capturedImage = savedStateHandle.get<String>(CNPHOTO)
        println("viewmodel->"+capturedImage)
        if(capturedImage != null && capturedImage.isNotEmpty())
            _state.update {
                it.copy(
                    image = capturedImage
                )
            }
    }

This is my navgraph

composable(
            route = "${HealthScreen.HealthCreateNutritionScreen.route}?$CNPHOTO={$CNPHOTO}",
            arguments = listOf(
                navArgument(name = CNPHOTO) {
                    type = NavType.StringType
                    defaultValue = ""
                })
        ) {
       
            CreateNutritionRoute(navHostController = navHostController)
        }

and this happens

choose content://com.android.providers.media.documents/document/image%3A54 

viewmodel->content://com.android.providers.media.documents/document/image:54

they are different from each other as you can see. so the image doesn't show. I cant see the image on the screen when I choose an image from the gallery. What is the problem I couldn't solve it?

Upvotes: 0

Views: 159

Answers (1)

Ratko Kostov
Ratko Kostov

Reputation: 31

As i can see the problem that you are facing is that the uri in the viewModel is encoded, ":" -> "%3A". When you place your 'imageUri' directly into the navigation route, it gets URL-encoded. So try decode it before using.

val capturedImage = savedStateHandle.get<String>(CNPHOTO)?.let { URLDecoder.decode(it, "UTF-8") }

Upvotes: 0

Related Questions