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
相关产品推荐
相关产品推荐

