Android - 快速获取隐藏图像和文件夹的方法

Android - fast way to get hidden images and folders

为了获取设备上的所有图像,我在 ContentResolver 中查询 MediaStore.Images。现在我想添加一个选项来显示隐藏文件,就像许多图像应用程序(如 QuickPic)一样。

有没有比递归搜索 phone 上的所有目录并检查其中是否有 .nomedia 文件更快的方法,如果有,请检查我是否可以在其中找到一些图像文件?

不可能通过 ContentResolver 是吗?

您可以在 SD 卡上对扩展名为 .nomedia

的文件夹中的文件进行迭代搜索

这是函数的代码片段,return 根据输入的文件类型在文件 ArrayList 卡中搜索结果。

  ArrayList<File> fileList = new ArrayList<File>();

    enum FileType {
        DOCUMENT,
        MUSIC,
        VIDEO,
        IMAGES,
        HIDDEN
    }

    /**
     * 
     * @param dir to serch in
     * @param fileType //pass fileType as a music , video, etc.
     * @return ArrayList of files of comes under fileType cataegory
     */
    public ArrayList<File> getAllFilesInDirectory(File dir, FileType fileType)
    {
        File listFile[] = dir.listFiles();

        if (listFile != null && listFile.length > 0) {
            for (int i = 0; i < listFile.length; i++) {
                if (listFile[i].isDirectory()) {
                    getAllFilesInDirectory(listFile[i], fileType);
                } else {

                    switch (fileType) {
                        case DOCUMENT:
                            if (listFile[i].getName().endsWith(".pdf") || listFile[i].getName().endsWith(".txt") ||
                                    listFile[i].getName().endsWith(".xml") || listFile[i].getName().endsWith(".doc") ||
                                    listFile[i].getName().endsWith(".xls") || listFile[i].getName().endsWith(".xlsx")) {
                                fileList.add(listFile[i]);
                            }

                            break;
                        case MUSIC:
                            if (listFile[i].getName().endsWith(".mp3")) {
                                fileList.add(listFile[i]);
                            }
                            break;

                        case VIDEO:
                            if (listFile[i].getName().endsWith(".mp4")) {
                                fileList.add(listFile[i]);
                            }
                            break;

                        case IMAGES:
                            if (listFile[i].getName().endsWith(".png") || listFile[i].getName().endsWith(".jpg")
                                    || listFile[i].getName().endsWith(".jpeg") || listFile[i].getName().endsWith(".gif")) {
                                fileList.add(listFile[i]);
                            }

                            break;

                        case HIDDEN:

                            if (listFile[i].getName().endsWith(".nomedia")) {
                                fileList.add(listFile[i]);
                            }
                            break;
                    }
                }
            }
        }

        return fileList;
    }

这种方法的优点在于它不仅限于搜索隐藏文件。您可以使用相同的方法搜索所有 IMAGESDOCUMENTVIDEOMUSIC 文件。

我正在添加另一个答案

  1. 快如闪电 :- 在我的测试应用程序中以 134 微秒执行扫描。
  2. 使用 ContentResolver :- 使用 ContentResolver 扫描所有包含 .noMedia 文件的隐藏文件夹,然后检查该文件夹是否有任何图像文件。您也可以轻松地将代码修改为 return 隐藏图像文件列表。

我制作了一个虚拟应用程序来测试我的代码,这里是输出

您可以看到测试应用程序显示 WhatsApp 的 Sent Images 文件夹有隐藏图像,但同时 Video 文件夹有 none(根据要求)。

怎么做

问题可以分成几部分

1) 首先在 content resolver 的帮助下获取所有包含 .noMedia 文件的目录。下面的代码片段是不言自明的

private static final String FILE_TYPE_NO_MEDIA = ".nomedia";


/**
     * This function return list of hidden media files
     * 
     * @param context
     * @return list of hidden media files
     */
    private ArrayList<CustomFile> filterFiles(Context context) {

        ArrayList<CustomFile> listOfHiddenFiles = new ArrayList<CustomFile>();
        String hiddenFilePath;

        // Scan all no Media files
        String nonMediaCondition = MediaStore.Files.FileColumns.MEDIA_TYPE
                + "=" + MediaStore.Files.FileColumns.MEDIA_TYPE_NONE;

        // Files with name contain .nomedia
        String where = nonMediaCondition + " AND "
                + MediaStore.Files.FileColumns.TITLE + " LIKE ?";

        String[] params = new String[] { "%" + FILE_TYPE_NO_MEDIA + "%" };

        // make query for non media files with file title contain ".nomedia" as
        // text on External Media URI
        Cursor cursor = context.getContentResolver().query(
                MediaStore.Files.getContentUri("external"),
                new String[] { MediaStore.Files.FileColumns.DATA }, where,
                params, null);

        // No Hidden file found
        if (cursor.getCount() == 0) {

            listOfHiddenFiles.add(new CustomFile("No Hidden File Found",
                    "Nothing to show Here", "Nothing to show Here", false));

            // show Nothing Found
            return listOfHiddenFiles;
        }

        // Add Hidden file name, path and directory in file object
        while (cursor.moveToNext()) {
            hiddenFilePath = cursor.getString(cursor
                    .getColumnIndex(MediaStore.Files.FileColumns.DATA));
            if (hiddenFilePath != null) {

                listOfHiddenFiles
                        .add(new CustomFile(FileUtils
                                .getFileName(hiddenFilePath), hiddenFilePath,
                                FileUtils.getFileParent(hiddenFilePath),
                                isDirHaveImages(FileUtils
                                        .getFileParent(hiddenFilePath))));
            }
        }

        cursor.close();

        return listOfHiddenFiles;

    }

2) 现在是拼图的第二部分 如何查找包含 .noMedia 文件的目录中是否有隐藏图像。

解决方案是使用简单的 for 循环来检查目录中的任何文件是否有图像文件扩展名(.jpg、.png 等),如果是,则中断循环并设置标志,当前目录有一些隐藏图像在里面。

在这里,您可以使用我第一个答案中的函数 return 图像列表,而不是破坏 for loop。**

/**
     * 
     * @param dir
     *            to serch in
     * @param fileType
     *            //pass fileType as a music , video, etc.
     * @return ArrayList of files of comes under fileType cataegory
     */
    public boolean isDirHaveImages(String hiddenDirectoryPath) {

        File listFile[] = new File(hiddenDirectoryPath).listFiles();

        boolean dirHaveImages = false;

        if (listFile != null && listFile.length > 0) {
            for (int i = 0; i < listFile.length; i++) {

                if (listFile[i].getName().endsWith(".png")
                        || listFile[i].getName().endsWith(".jpg")
                        || listFile[i].getName().endsWith(".jpeg")
                        || listFile[i].getName().endsWith(".gif")) {

                    // Break even if folder have a single image file
                    dirHaveImages = true;
                    break;

                }
            }
        }
        return dirHaveImages;

    }

现在回到你的问题

  • Is there a faster way than recursively searching all directories on
    the phone and check if a .nomedia file is in it?

    参见代码片段 1

    -

and if so, check if I can find some image file in it?

参见代码片段 2

  • It's not possible through the ContentResolver is it?

是的!!

我已经在Github上上传了整个样本,你可以下载修改