【发布时间】:2021-09-09 01:31:48
【问题描述】:
我有一个呼叫者应用程序,它允许用户从他们的手机中为联系人挑选照片和为铃声挑选音频文件。 当我拿起照片时,它可以使用界面上的URI正确显示。在主页和联系页面上。 我将它保存在房间数据库中......
如果我关闭应用程序并重新打开它,它会从 db 获取相同的 URI。但不显示图像。不在主页或联系页面上。
我尝试手动插入 URI 代码,它也没有显示任何内容...还将图像加载器从 rememberImagePainter 更改为 GlideImage (另一个实现)但同样的问题...
我从 db 和图像选择器获得的 URI 看起来像这样
val uri2:Uri = "content://com.android.providers.media.documents/document/image%3A34".toUri()
获取图片Uri的代码是这样的
class GetContentActivityResult(
private val launcher: ManagedActivityResultLauncher<String, Uri>,
val uri: Uri?
) {
fun launch(mimeType: String) {
launcher.launch(mimeType)
}
}
@Composable
fun rememberGetContentActivityResult(): GetContentActivityResult {
var uri by rememberSaveable { mutableStateOf<Uri?>(null) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent(), onResult = {
uri = it
})
return remember(launcher, uri) { GetContentActivityResult(launcher, uri) }
}
我像这样在联系页面中显示图像
val getContent = rememberGetContentActivityResult() <-- to access the class of pickup files
if (roomViewModel.photoUri.value.isBlank()){ <-- if no image from db display the picked image using image picker
getContent.uri?.let {
Image(
modifier = Modifier
.align(Alignment.TopCenter)
.fillMaxSize(1f),
contentDescription = "UserImage",
contentScale = ContentScale.Crop,
painter = rememberImagePainter(data = it))
}
}else{
Image(
modifier = Modifier
.align(Alignment.TopCenter)
.fillMaxSize(1f),
contentDescription = "UserImage",
contentScale = ContentScale.Crop,
painter = rememberImagePainter(data = roomViewModel.photoUri.value))
}
}
TextButton(
onClick = { getContent.launch("image/*") }, <-- launching the class to get the image URI by defining the Mime as image/*
modifier = Modifier.layoutId("changePhoto")
) {
Text(
text = "Change Photo",
color = Color.Black)}
在主页内。没有图像选择器,我只是显示数据库中的数据,然后以这种方式显示图像
@OptIn(ExperimentalCoilApi::class)
@Composable
fun ProfilePicture(uri : Uri, imageSize: Dp) {
Card(
shape = CircleShape,
border = BorderStroke(
width = 2.dp,
color = Color.Red ),
modifier = Modifier.padding(16.dp),
elevation = 4.dp) {
val uri2:Uri = "content://com.android.providers.media.documents/document/image%3A34".toUri() //<-- i tried to load the image this way also it didn't work.
val painter = rememberImagePainter(
data = uri,
builder = {
placeholder(R.drawable.yara) <-- the placeholder image blinks quickly when app is loaded and then disappear...
}
)
Image(
painter = painter,
contentDescription = "User Image",
modifier = Modifier.size(imageSize) )
}
}
这是 Uri 选择器或图像显示的问题吗?
房间数据库中的其他内容正确显示(字符串)
我尝试在模拟器和真实设备上使用代码,这两种情况都是一样的......
我刚刚注意到的一件事...如果我使用图像选择器并选择以前选择的图像(它的 uri 在数据库中),图像会自动显示在应用程序的其他位置,而无需执行任何其他操作...只是选择图像并显示它甚至不保存它......
【问题讨论】:
-
请格式化您的代码以便可读
-
更好?我在最后添加了一条注释...您认为问题是我应该使用协程而不是这种方式来加载图像吗?
-
不要将
Uri值保存在数据库(或任何其他类型的文件)中。或者,切换到OpenDocument而不是GetContent并使用takePersistableUriPermission()来获得对内容的持久访问。否则,your rights to access the content will be short-lived. -
当您选择带有
ActivityResultContracts.GetContent()的图像时,系统会给您一个临时URL。在一个会话期间使用它很好,但如果你想存储它 - 你需要将它复制到你的应用存储中 -
我确实将它保存在房间里,并检查了选择器返回的结果,它是相同的 Uri...是关于
takePersistableUriPermission()还是按照链接建议添加一个标志?
标签: android uri android-jetpack-compose