You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加载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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 01:05:54