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

Kotlin安卓:获取视频文件夹大小及文件数量的问题求助

视频播放器文件夹大小与视频数量统计解决方案

核心问题分析

通常获取文件夹大小和视频数量失败的原因包括:

  • 未按文件夹路径正确分组视频文件
  • 计算文件夹大小时未处理文件权限或路径错误问题
  • 未在子线程异步计算大小,导致主线程阻塞或计算中断
  • 数据模型未预留存储文件夹统计信息的字段

最优解决方案步骤

1. 定义文件夹数据模型(FolderItem.kt)

先创建专门的文件夹数据类,统一存储文件夹的核心信息:

data class FolderItem(
    val folderPath: String,
    val folderName: String,
    var videoCount: Int = 0,
    var totalSize: Long = 0L,
    val videoList: MutableList<VideoItem> = mutableListOf()
)

2. 按文件夹分组并统计数据

在获取到ArrayList<VideoItem>后,按文件夹路径分组,同步计算视频数量和总大小:

// 假设已从MediaStore获取到视频列表:val videoList: ArrayList<VideoItem>
val folderMap = mutableMapOf<String, FolderItem>()

videoList.forEach { videoItem ->
    // 提取视频所在文件夹的绝对路径和名称
    val folderPath = videoItem.filePath.substringBeforeLast("/")
    val folderName = folderPath.substringAfterLast("/").takeIf { it.isNotEmpty() } ?: "根目录"

    // 复用已存在的FolderItem,不存在则创建新实例
    val folderItem = folderMap.getOrPut(folderPath) {
        FolderItem(folderPath, folderName)
    }

    folderItem.videoList.add(videoItem)
    folderItem.videoCount++
    // 累加文件大小,需确保VideoItem已存储fileSize字段(从MediaStore的SIZE列获取)
    folderItem.totalSize += videoItem.fileSize
}

// 转换为Adapter可用的列表
val folderList = folderMap.values.toList()

3. 权限处理与异步计算

必须确保已申请对应权限(Android 13+用READ_MEDIA_VIDEO,低版本用READ_EXTERNAL_STORAGE),且在子线程中完成计算避免阻塞UI:

// 推荐在ViewModel中用协程处理
viewModelScope.launch(Dispatchers.IO) {
    // 若MediaStore获取的size为空,手动读取文件大小
    videoList.forEach { videoItem ->
        if (videoItem.fileSize == 0L) {
            val file = File(videoItem.filePath)
            if (file.exists() && file.canRead()) {
                videoItem.fileSize = file.length()
            }
        }
    }

    // 执行分组统计逻辑(同步骤2)
    val folderMap = mutableMapOf<String, FolderItem>()
    videoList.forEach { ... }

    // 切回主线程更新UI
    withContext(Dispatchers.Main) {
        folderAdapter.submitList(folderMap.values.toList())
    }
}

4. FolderAdapter绑定数据

在Adapter中直接调用FolderItem的统计字段即可:

override fun onBindViewHolder(holder: FolderViewHolder, position: Int) {
    val folderItem = folderList[position]
    holder.folderName.text = folderItem.folderName
    holder.videoCount.text = "${folderItem.videoCount} 个视频"
    holder.folderSize.text = formatFileSize(folderItem.totalSize)
}

// 辅助方法:将字节数格式化为可读的大小单位
private fun formatFileSize(size: Long): String {
    return when {
        size >= 1024 * 1024 * 1024 -> String.format("%.2f GB", size.toDouble() / (1024 * 1024 * 1024))
        size >= 1024 * 1024 -> String.format("%.2f MB", size.toDouble() / (1024 * 1024))
        size >= 1024 -> String.format("%.2f KB", size.toDouble() / 1024)
        else -> "$size B"
    }
}

5. 常见错误排查

  • 路径错误:确保VideoItem的filePath是绝对路径,Android Q+建议使用MediaStore.Video.Media.RELATIVE_PATH替代废弃的DATA列
  • 权限缺失:在AndroidManifest中声明权限,并在运行时主动申请
    <!-- Android 12及以下 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- Android 13及以上 -->
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
    
  • MediaStore字段遗漏:查询时必须包含MediaStore.Video.Media.SIZE列,否则无法获取文件大小

补充说明

如果你的现有代码存在特定逻辑错误(比如分组逻辑混乱、权限处理不当),可以提供具体代码片段,我会给出针对性修改方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:00:11