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

Android中访问CameraView录制视频路径及Kotlin最优视频存储方案咨询

如何访问当前生成路径下的视频文件

你当前保存视频的路径是通过getExternalFilesDir(Environment.DIRECTORY_MOVIES)生成的应用专属外部存储目录,该目录默认仅你的应用自身有读写权限,系统自带的文件管理器默认不会展示应用专属目录的内容,所以你无法直接找到文件,访问方式如下:

  • 应用内直接访问:直接使用你代码中拿到的videoPath或videoUri即可完成读写操作,所有Android版本都不需要额外申请存储权限
  • 调试阶段查看:打开Android Studio的Device File Explorer,进入路径sdcard/Android/data/com.example.testgogoapplication/files/Movies即可找到对应视频,支持直接导出到本地电脑
  • 系统文件管理器查看:将视频移动到公共媒体目录(如DCIM、公共Movies目录)后,即可在系统相册、文件管理器中正常显示

你贴出的原有创建文件代码如下:

@Throws(IOException::class)
private fun createVideoFile(): File {
    // Create an image file name
    val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_MOVIES)
    return File.createTempFile(
        "oogoo_${timeStamp}_",
        ".mp4",
        storageDir
    ).apply {
        videoPath = this.path
        videoUri = this.toUri()
    }
}

现有日志输出如下:

D/VideoTaken: /storage/emulated/0/Android/data/com.example.testgogoapplication/files/Movies/oogoo_20211021_125639_3062139219833544197.mp4
file:///storage/emulated/0/Android/data/com.example.testgogoapplication/files/Movies/oogoo_20211021_125639_3062139219833544197.mp4

这里注意你当前用了createTempFile创建临时文件,如果你需要长期留存视频,不要用临时文件创建方式,临时文件可能会被系统自动清理。


Kotlin保存视频到存储的最优实现

根据使用场景分为两种最优方案:

场景1:视频仅在你的应用内使用

直接使用应用专属外部存储方案,无需申请任何权限,兼容全Android版本,优化后的代码如下:

@Throws(IOException::class)
private fun createAppPrivateVideoFile(): File {
    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
    val storageDir = getExternalFilesDir(Environment.DIRECTORY_MOVIES)
    // 直接创建普通文件而非临时文件,避免被系统自动清理
    val videoFile = File(storageDir, "oogoo_${timeStamp}.mp4")
    videoPath = videoFile.absolutePath
    videoUri = videoFile.toUri()
    return videoFile
}

场景2:视频需要对外暴露,可在系统相册、其他应用中访问

使用MediaStore API适配分区存储规则,Android 10及以上不需要申请存储权限,Android 9及以下仅需申请WRITE_EXTERNAL_STORAGE权限,示例代码如下:

@RequiresApi(Build.VERSION_CODES.Q)
private fun saveVideoToPublicDirectory(context: Context, sourceVideoFile: File): Uri? {
    val contentValues = ContentValues().apply {
        put(MediaStore.Video.Media.DISPLAY_NAME, "oogoo_${System.currentTimeMillis()}.mp4")
        put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
        put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES + "/Oogoo")
        put(MediaStore.Video.Media.IS_PENDING, 1) // 标记文件正在写入,避免其他应用提前读取
    }

    val contentResolver = context.contentResolver
    val targetUri = contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues) ?: return null

    // 将已生成的视频内容写入公共目录Uri
    contentResolver.openOutputStream(targetUri)?.use { outputStream ->
        FileInputStream(sourceVideoFile).use { inputStream ->
            inputStream.copyTo(outputStream)
        }
    }

    // 写入完成,更新文件状态为可访问
    contentValues.clear()
    contentValues.put(MediaStore.Video.Media.IS_PENDING, 0)
    contentResolver.update(targetUri, contentValues, null, null)

    // 若不需要保留应用私有目录的副本,可在此处删除源文件
    // sourceVideoFile.delete()
    return targetUri
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:45:07