Search code examples
androidkotlinandroid-roomandroid-jetpack-compose

Why local images saved in Room database are not displayed after i restart an app?


I'm saving uri's as a string in Room database, then the app is retrieving data and displaying all the images in the LazyVerticalGrid. When i add images, everything works fine, all the images are displayed correctly. The problem is when i restart an app. All the images disappears and when i add exactly the same image (with the same uri) - it appear in the first position, but also in all the positions before i restarted an app. When i check the logs, all uri's are also retrieved correctly from database as format:

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

Here is the code for Image showing (using coil):

@Composable
fun ProfilePhotoView(photo: String, navController: NavHostController) {
    Image(
        painter = rememberImagePainter(photo),
        contentDescription = null,
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .aspectRatio(1f)
            .padding(3.dp)
            .clip(RoundedCornerShape(10.dp))
            .clickable {},
        alignment = Alignment.Center
    )
    Log.i(TAG,"photo string = ${photo}")
}

And here is how i retrieve an uri before adding to database:

val selectImagelauncher = rememberLauncherForActivityResult(
        contract =
        ActivityResultContracts.GetContent()
    ) { uri: Uri? ->
        imageUriState = uri
    }
selectImagelauncher.launch("image/*")

Do you have any idea why i can't display images with "old" uri before adding the same image into database?


Solution

  • I'm saving uri's as a string in Room database

    With your existing code, that will not work. Normally, you only have access rights to the content from within the activity that receives the Uri. Once your process terminates, all access rights are lost.

    If you change ActivityResultContracts.GetContent() to ActivityResultContracts.OpenDocument(), and you call takePersistableUriPermission() on a ContentResolver for the Uri that you get, then you have long-term access to the content.