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

Android如何通过代码获取内部存储中带视频的点开头隐藏文件夹

核心原因

Android系统默认的媒体扫描服务不会索引名称以.开头的目录下的媒体文件,这类文件不会被写入MediaStore数据库,所以你通过ContentResolver查询MediaStore的接口自然拉取不到对应数据。

前提权限配置

要扫描全量内部存储的隐藏目录,你需要申请对应权限:

  • Android 13及以上:先申请READ_MEDIA_VIDEO,再引导用户开启「所有文件访问权限」(即MANAGE_EXTERNAL_STORAGE权限)
  • Android 11~12:直接申请MANAGE_EXTERNAL_STORAGE权限
  • Android 10及以下:申请READ_EXTERNAL_STORAGE权限即可

可行解决方案

推荐用MediaStore查询+隐藏目录手动遍历的混合方案,兼顾效率和覆盖度:

  1. 先用你现有代码从MediaStore拉取所有非隐藏目录的视频文件,这部分查询速度快,不用自己遍历
  2. 手动递归遍历内部存储根目录下所有名称以.开头的文件夹,匹配后缀为常见视频格式的文件,补入你的媒体列表
  3. 按文件父目录路径去重,即可拿到所有包含视频的文件夹(含隐藏目录)

手动遍历隐藏目录的示例代码

// 常见视频后缀集合
private static final String[] VIDEO_EXTENSIONS = {".mp4", ".avi", ".mkv", ".mov", ".wmv", ".flv", ".rmvb", ".webm"};

// 遍历指定目录,收集所有视频文件
private void scanHiddenDirs(File dir, ArrayList<MediaFiles> mediaFilesArrayList, HashSet<String> allFolderList) {
    // 跳过无访问权限的系统目录
    if (dir == null || !dir.exists() || !dir.canRead() || dir.getAbsolutePath().startsWith("/sdcard/Android/")) {
        return;
    }
    File[] files = dir.listFiles();
    if (files == null) return;
    for (File file : files) {
        if (file.isDirectory()) {
            // 递归遍历所有子目录
            scanHiddenDirs(file, mediaFilesArrayList, allFolderList);
        } else {
            // 判断是不是视频文件
            String fileName = file.getName();
            for (String ext : VIDEO_EXTENSIONS) {
                if (fileName.toLowerCase().endsWith(ext)) {
                    // 构造MediaFiles对象
                    String path = file.getAbsolutePath();
                    String parentPath = path.substring(0, path.lastIndexOf("/"));
                    // 去重添加文件夹
                    SharedPreferences sharedPreferences = getSharedPreferences(HIDDEN_VIDEOS_PREFS, MODE_PRIVATE);
                    if (!allFolderList.contains(parentPath) && sharedPreferences.getString(HIDDEN_VIDEO_KEY + parentPath, "-").equals("-")) {
                        allFolderList.add(parentPath);
                    }
                    // 补入媒体列表
                    MediaFiles mediaFile = new MediaFiles(
                        String.valueOf(file.hashCode()), // 自定义唯一id
                        fileName.substring(0, fileName.lastIndexOf(".")), // 视频标题
                        String.valueOf(getVideoDuration(path)), // 可用MediaMetadataRetriever获取时长
                        String.valueOf(file.length()), // 文件大小
                        String.valueOf(file.lastModified()/1000), // 转换为秒级时间戳
                        path,
                        fileName,
                        false
                    );
                    mediaFilesArrayList.add(mediaFile);
                    break;
                }
            }
        }
    }
}

调用方法

在你原有fetchMedia方法执行完毕后,调用遍历方法补全隐藏目录的内容:

// 原有MediaStore查询逻辑执行完后添加此行,传入内部存储根目录
scanHiddenDirs(Environment.getExternalStorageDirectory(), mediaFilesArrayList, allFolderList);

注意事项

  • 拿视频时长的getVideoDuration方法可以用MediaMetadataRetriever自行封装,大文件较多的话建议放在子线程执行避免卡顿
  • 必须等用户授予所有文件访问权限后再执行遍历操作,否则会出现无权限读取的问题
  • 可以按需新增过滤规则,排除不需要扫描的目录提升执行效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:54:06