如何加载Room中存储为字符串的URI图片?解决重启后图片消失问题
商店库存管理应用图片持久化问题
我正在开发一个商店库存管理练习应用,流程为:点击悬浮按钮弹出对话框,用户从相册选择图片,点击保存后将图片及其他数据存入ViewModel与Room,主界面生成展示项并通过Log.d打印数据。
当前问题:保存后生成的项能正常显示图片,但重启应用后图片消失,两次Log.d打印的URI完全一致。
需求目标:将图片、其路径或URI存入Room并正常加载展示。经调研,将URI存为字符串是可行方案,但不清楚图片存储的规范做法,也接受其他解决方案。
现有代码实现
1. 从相册选择图片并保存到ViewModel
val singlePhotoPickerLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.PickVisualMedia(), onResult = { uri -> selectedImageUri = uri Log.d("URI RESULT", "$uri") viewModel.onDialogChanged( uri.toString() ) } )
2. 点击保存按钮存入Room
保存按钮逻辑
DialogButton( ButtonDefaults.buttonColors( backgroundColor = verdeBillete, contentColor = Color.White ), "Guardar", modifier = Modifier, onClick = { viewModel.viewModelScope.launch { viewModel.onAddSelected( inventoryItem( 0, uri, ) ) } onDismiss() })
ViewModel添加逻辑
fun onAddSelected(addItem: inventoryItem) { viewModelScope.launch { addItem(addItem) getInventory() } }
Room实体类
@Entity(tableName = "inventory") data class inventoryItem( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "r_id") var id: Int = 0, @ColumnInfo(name = "r_uri") val uri: String, )
3. 加载图片的代码
Log.d("Loading items", item.uri) AsyncImage( model = Uri.parse(item.uri), contentDescription = null, modifier = Modifier.fillMaxWidth(), contentScale = ContentScale.Crop )
已申请权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
解决方案更新
通过takePersistableUriPermission获取持久化URI权限,解决重启后图片消失问题。完整实现代码如下:
var selectedImageUri by remember { mutableStateOf<Uri?>(null) } val singlePhotoPickerLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.PickVisualMedia(), onResult = { uri -> selectedImageUri = uri Log.d("URI RESULT", "$uri") val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION//or Intent.FLAG_GRANT_WRITE_URI_PERMISSION val resolver = mContext.contentResolver resolver.takePersistableUriPermission(uri!!, flags) viewModel.onDialogChanged( //**save to database function** uri.toString() ) } )
内容的提问来源于stack exchange,提问作者Carlos Rosiles
相关产品推荐
相关产品推荐

