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

时间:2015-09-29 09:19:42

标签: android android-contentresolver mediastore

要获取设备上的所有图片,我会ContentResolver查询MediaStore.Images。现在我想添加一个显示隐藏文件的选项,以及像QuickPic这样的许多图像应用程序。

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

通过ContentResolver无法实现吗?

2 个答案:

答案 0 :(得分:12)

我正在添加另一个

的答案
  1. 快速闪电: - 在我的测试应用中以134微秒执行扫描。
  2. 使用ContentResolver : - 使用ContentResolver扫描包含.noMedia文件的所有隐藏文件夹,然后检查该文件夹是否包含任何图像文件。您可以轻松修改代码以返回隐藏图像文件列表。
  3. 我制作了一个虚拟应用程序来测试我的代码,这里是输出

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

    Hidden Images in whatsApp

    如何操作

    问题可分为部分

    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等),如果是真的打破循环并设置标志,当前目录中有一些隐藏的图像

    此处不是打破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;
    
        }
    

    现在回到你的问题

    •   

      有没有比递归搜索上所有目录更快的方法   电话并检查是否有.nomedia个文件?

      请参阅代码段1

      -

      

    如果是,请检查我是否可以在其中找到一些图像文件?

    请参阅代码段2

    •   

      通过ContentResolver是不可能的?

    是的!!

    我已在Github上传整个样本,您可以根据需要下载和修改

答案 1 :(得分:0)

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

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

这是函数的代码片段,它根据输入的fileType将搜索结果返回到文件卡的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;
    }

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