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

Android中如何通过registerActivityResult获取录制视频的URI?

问题分析与修复方案

你代码中的编译报错主要来自以下几个核心问题,我会逐一说明并给出修正后的完整代码:

关键错误点

  1. 回调参数类型不匹配:ActivityResultContracts.CaptureVideo()的回调接收的是Boolean类型(表示录制是否成功),而非Uri?,你写的{ uri: Uri? ->会直接导致类型不匹配编译错误。
  2. 未定义变量引用:recordVideoResult.launch(this.uri)中的this.uri是不存在的变量,你声明的成员变量是videoUri,且即使改成videoUri,未初始化的null值也不符合CaptureVideo的参数要求(必须传入有效存储Uri)。
  3. 缺少视频存储Uri创建逻辑:录制视频需要提前生成一个系统可写入的Uri,用于存储录制后的视频文件。

修正后的完整代码

1. 成员变量声明

private var videoUri: Uri? = null

2. 注册Activity Result Launcher

// 视频录制结果回调:参数是Boolean,表示录制是否成功
private val recordVideoResult = registerForActivityResult(ActivityResultContracts.CaptureVideo()) { isRecordingSuccess ->
    if (isRecordingSuccess) {
        // 录制成功,videoUri就是视频的存储路径
        Toast.makeText(this, "视频录制完成", Toast.LENGTH_SHORT).show()
    } else {
        // 录制取消或失败,清空无效的Uri
        videoUri = null
        Toast.makeText(this, "视频录制取消或失败", Toast.LENGTH_SHORT).show()
    }
}

// 相机权限申请回调
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted ->
    if (isGranted) {
        launchCamera()
    } else {
        Toast.makeText(this, "无法打开相机:权限被拒绝,请在设置中开启权限", Toast.LENGTH_SHORT).show()
    }
}

3. 添加视频存储Uri创建方法

该方法适配Android 10+的分区存储规则,无需额外申请存储权限(Android 9及以下需在Manifest中声明WRITE_EXTERNAL_STORAGE权限):

private fun createVideoUri(): Uri? {
    val videoFileName = "录制视频_${System.currentTimeMillis()}.mp4"
    val contentValues = ContentValues().apply {
        put(MediaStore.Video.Media.DISPLAY_NAME, videoFileName)
        put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
        // Android 10+ 指定存储到系统Movies目录
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES)
        }
    }

    return contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues)
}

4. 修正相机启动方法

fun launchCamera() {
    if (packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
        when {
            ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED -> {
                // 先创建视频存储Uri,再启动相机
                videoUri = createVideoUri()
                videoUri?.let { uri ->
                    recordVideoResult.launch(uri)
                } ?: run {
                    Toast.makeText(this, "创建视频文件失败", Toast.LENGTH_SHORT).show()
                }
            }
            else -> {
                requestPermissionLauncher.launch(Manifest.permission.CAMERA)
            }
        }
    } else {
        Toast.makeText(this, "设备无可用相机", Toast.LENGTH_SHORT).show()
    }
}

额外注意事项

在AndroidManifest.xml中声明必要权限:

<uses-permission android:name="android.permission.CAMERA" />
<!-- 兼容Android 9及以下的存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />

registerForActivityResult必须在Activity/Fragment的创建阶段(如onCreate方法、成员变量初始化)注册,不能在点击事件等动态场景中注册。

内容的提问来源于stack exchange,提问作者Darrell Gehring

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:30:49