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

Android:从云端存储下载的视频无法在相册顶部显示的问题

解决Android下载视频后相册显示云端原时间戳的问题

问题说明

通过代码从Google Cloud Storage下载视频到Android设备的DCIM目录,已在ContentValues中设置DATE_ADDED、DATE_TAKEN、DATE_MODIFIED为当前时间,但相册仍显示视频上传至云端时的原始时间戳,无法置顶为最新视频。

原因分析

相册应用优先读取视频文件内部的元数据(如EXIF中的拍摄时间),而非MediaStore中存储的字段。你的代码仅修改了MediaStore的记录,但视频文件本身的元数据还是云端的旧时间,因此相册会显示原始时间戳。另外,写入视频文件后,系统媒体扫描可能会重新从文件元数据提取信息覆盖MediaStore的设置。

解决方案

需要两步操作:

  • 视频写入完成后,再次更新MediaStore中的时间字段,确保系统扫描后记录正确。
  • 修改视频文件本身的元数据,将内部的拍摄/修改时间改为当前时间。

修改后的代码

var fos: OutputStream? = null
var videoUri: Uri? = null
contentResolver?.also { resolver ->
    val contentValues = ContentValues().apply {
        put(MediaStore.Video.Media.DISPLAY_NAME, "file.mp4")
        put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
        // 注意:DATE_ADDED/DATE_MODIFIED单位是秒,DATE_TAKEN是毫秒
        val currentTime = System.currentTimeMillis()
        put(MediaStore.Video.Media.DATE_ADDED, currentTime / 1000)
        put(MediaStore.Video.Media.DATE_TAKEN, currentTime)
        put(MediaStore.Video.Media.DATE_MODIFIED, currentTime / 1000)
    }
    videoUri = resolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues)
    fos = videoUri?.let { resolver.openOutputStream(it) }
}

// 写入视频文件
val buffer = ByteArray(8192)
URL(weblink).openStream().use { input ->
    fos.use { fileOut ->
        var length: Int
        while (input.read(buffer).also { length = it } > 0) {
            fileOut?.write(buffer, 0, length)
        }
        fileOut?.flush()
    }
}

// 步骤1:写入完成后更新MediaStore时间字段
videoUri?.let { uri ->
    contentResolver?.also { resolver ->
        val updateValues = ContentValues().apply {
            val currentTime = System.currentTimeMillis()
            put(MediaStore.Video.Media.DATE_ADDED, currentTime / 1000)
            put(MediaStore.Video.Media.DATE_TAKEN, currentTime)
            put(MediaStore.Video.Media.DATE_MODIFIED, currentTime / 1000)
        }
        resolver.update(uri, updateValues, null, null)
    }
}

// 步骤2:修改视频文件自身元数据(API 26+支持)
videoUri?.let { uri ->
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        contentResolver?.openFileDescriptor(uri, "rw")?.use { fd ->
            ExifInterface(fd.fileDescriptor).apply {
                val currentTime = System.currentTimeMillis()
                val dateString = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.getDefault()).format(Date(currentTime))
                // 修改EXIF中所有时间相关字段
                setAttribute(ExifInterface.TAG_DATETIME, dateString)
                setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL, dateString)
                setAttribute(ExifInterface.TAG_DATETIME_DIGITIZED, dateString)
                saveAttributes()
            }
        }
    }
}

// 可选:发送广播强制相册刷新
videoUri?.let {
    Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).also { intent ->
        intent.data = it
        sendBroadcast(intent)
    }
}

补充说明

  • 你之前的代码中DATE_ADDED用了毫秒单位,这是错误的,该字段要求用秒作为单位,会导致时间显示异常。
  • 对于Android 7.1及以下版本,系统ExifInterface不支持修改视频元数据,可使用第三方库(如metadata-extractor)实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:27:41