为什么Room数据库中保存的本地图片在重启应用后不显示?
Why local images saved in Room database are not displayed after i restart an app?
我将 uri 作为字符串保存在 Room 数据库中,然后应用程序检索数据并显示 LazyVerticalGrid 中的所有图像。当我添加图像时,一切正常,所有图像都正确显示。问题是当我重新启动应用程序时。所有图像都消失了,当我添加完全相同的图像(具有相同的 uri)时 - 它出现在第一个位置,但在我重新启动应用程序之前也出现在所有位置。当我检查日志时,所有 uri 也从数据库中以格式正确检索:
内容://com.android.providers.media.documents/document/image%3A9371
这是显示图像的代码(使用线圈):
@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}")
}
这是我在添加到数据库之前检索 uri 的方式:
val selectImagelauncher = rememberLauncherForActivityResult(
contract =
ActivityResultContracts.GetContent()
) { uri: Uri? ->
imageUriState = uri
}
selectImagelauncher.launch("image/*")
你知道为什么在将相同图像添加到数据库之前我无法显示带有“旧”uri 的图像吗?
I'm saving uri's as a string in Room database
使用您现有的代码,那是行不通的。通常,you only have access rights to the content from within the activity that receives the Uri
。一旦您的进程终止,所有访问权限都将丢失。
如果您将 ActivityResultContracts.GetContent()
更改为 ActivityResultContracts.OpenDocument()
,并且您在 ContentResolver
上调用 takePersistableUriPermission()
以获得 Uri
,那么您有很长的时间-term 访问内容。
创建你自己的 ActivityResultContract,
针对您的情况
contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
这是在拾取 Uri
之后
class GetPicturesContract : ActivityResultContract<String, Uri?>() {
override fun createIntent(context: Context, input: String?): Intent {
return Intent(Intent.ACTION_OPEN_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.setType(input)
}
override fun getSynchronousResult(
context: Context,
input: String
): SynchronousResult<Uri?>? {
return null
}
override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
return if (intent == null || resultCode != Activity.RESULT_OK) null else intent.data
}
}
我将 uri 作为字符串保存在 Room 数据库中,然后应用程序检索数据并显示 LazyVerticalGrid 中的所有图像。当我添加图像时,一切正常,所有图像都正确显示。问题是当我重新启动应用程序时。所有图像都消失了,当我添加完全相同的图像(具有相同的 uri)时 - 它出现在第一个位置,但在我重新启动应用程序之前也出现在所有位置。当我检查日志时,所有 uri 也从数据库中以格式正确检索:
内容://com.android.providers.media.documents/document/image%3A9371
这是显示图像的代码(使用线圈):
@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}")
}
这是我在添加到数据库之前检索 uri 的方式:
val selectImagelauncher = rememberLauncherForActivityResult(
contract =
ActivityResultContracts.GetContent()
) { uri: Uri? ->
imageUriState = uri
}
selectImagelauncher.launch("image/*")
你知道为什么在将相同图像添加到数据库之前我无法显示带有“旧”uri 的图像吗?
I'm saving uri's as a string in Room database
使用您现有的代码,那是行不通的。通常,you only have access rights to the content from within the activity that receives the Uri
。一旦您的进程终止,所有访问权限都将丢失。
如果您将 ActivityResultContracts.GetContent()
更改为 ActivityResultContracts.OpenDocument()
,并且您在 ContentResolver
上调用 takePersistableUriPermission()
以获得 Uri
,那么您有很长的时间-term 访问内容。
创建你自己的 ActivityResultContract, 针对您的情况
contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
这是在拾取 Uri
class GetPicturesContract : ActivityResultContract<String, Uri?>() {
override fun createIntent(context: Context, input: String?): Intent {
return Intent(Intent.ACTION_OPEN_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.setType(input)
}
override fun getSynchronousResult(
context: Context,
input: String
): SynchronousResult<Uri?>? {
return null
}
override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
return if (intent == null || resultCode != Activity.RESULT_OK) null else intent.data
}
}