Android Studio Kotlin中Uri空值错误及跨页面传递问题排查
解决方案:图片Uri传递与空值问题修复
1. 确保Uri权限与正确传递
使用ActivityResultContracts.PickVisualMedia获取的content://类型Uri受系统权限保护,跨页面传递时必须授予临时访问权限,同时直接传递Uri对象而非手动编码字符串,避免解析错误:
主页面回调与跳转代码
val pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri -> uri?.let { val intent = Intent(context, ImageRecognitionActivity::class.java).apply { putExtra("IMAGE_URI", it) // 关键:授予目标页面Uri读取权限 addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } context.startActivity(intent) } ?: run { Toast.makeText(context, "未选择图片", Toast.LENGTH_SHORT).show() } }
目标页面接收Uri
// 在目标Activity的onCreate或Composable中获取 val imageUri = intent.getParcelableExtra<Uri>("IMAGE_URI") imageUri?.let { // 执行图片加载与ML Kit识别逻辑 } ?: run { Toast.makeText(this, "图片Uri无效", Toast.LENGTH_SHORT).show() finish() }
2. 空值安全全链路处理
在所有涉及Uri的环节添加空值判断,避免触发FileNotFoundException:
- 回调中判断用户是否取消选择图片
- 目标页面接收时校验Uri是否为空
- 操作Uri前验证其有效性:
fun isUriValid(context: Context, uri: Uri): Boolean { return try { context.contentResolver.openInputStream(uri)?.use { true } ?: false } catch (e: Exception) { false } }
调用该方法返回false时,直接提示错误并终止后续流程。
3. 若使用NavHost跳转的适配方案
如果通过Jetpack Navigation的NavHost跳转,需对Uri字符串进行编码避免解析异常,同时确保权限传递:
// 主页面跳转 navController.navigate("recognition_screen?imageUri=${Uri.encode(uri.toString())}") // 目标页面接收 val imageUriString = remember { navController.currentBackStackEntry?.arguments?.getString("imageUri") } val imageUri = imageUriString?.let { Uri.parse(it) } // 授予权限(需在Activity上下文执行) imageUri?.let { context.grantUriPermission( context.packageName, it, Intent.FLAG_GRANT_READ_URI_PERMISSION ) }
4. 额外检查项
- 确保目标Activity在
AndroidManifest.xml中使用默认launchMode="standard",避免singleInstance等模式导致Intent数据丢失 - 不要手动对Uri进行不必要的编码/解码,直接传递Parcelable类型的Uri对象是最可靠的方式
内容的提问来源于stack exchange,提问作者Eduardo
相关产品推荐
相关产品推荐

