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

Android-快速获取隐藏图像和文件夹的方法,android,android-contentresolver,mediastore,Android,Android Contentresolver,Mediastore,为了获取设备上的所有图像,我查询了MediaStore.images的ContentResolver。现在我想添加一个选项来显示隐藏的文件,就像许多像QuickPic这样的图像应用一样 有没有比递归搜索手机上的所有目录并检查其中是否有.nomedia文件更快的方法?如果有,请检查是否可以在其中找到一些图像文件 无法通过内容解析程序实现,是吗?您可以在SD卡上反复搜索扩展名为.nomedia的文件夹中的文件 下面是函数的代码段,该函数根据输入文件类型在文件卡的ArrayList中返回搜索结果

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

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


无法通过
内容解析程序
实现,是吗?

您可以在SD卡上反复搜索扩展名为
.nomedia
的文件夹中的文件

下面是函数的代码段,该函数根据输入文件类型在文件卡的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;
    }
ArrayList fileList=new ArrayList();
枚举文件类型{
文件,
音乐,
视频
图像,
隐藏的
}
/**
* 
*@param dir到serch in
*@param fileType//将文件类型作为音乐、视频等传递。
*@return ArrayList的文件属于文件类型目录
*/
公共ArrayList GetAllFileIndirectory(文件目录,文件类型FileType)
{
文件listFile[]=dir.listFiles();
if(listFile!=null&&listFile.length>0){
for(int i=0;i

这种方法的优点在于它不仅限于搜索隐藏文件。您可以使用相同的方法搜索所有
图像
文档
视频
音乐
文件。

我正在添加另一个答案,它是

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

    您可以看到测试应用程序正在显示WhatsApp的
    发送图像
    文件夹中有隐藏图像,但同时
    视频
    文件夹中没有(根据要求)

    如何做到这一点

    问题可以分为几个部分

    1) 首先,在
    内容解析器的帮助下
    获取其中包含
    .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;
    
        }
    
    现在回到你的问题上来

    • 有没有比递归搜索上的所有目录更快的方法 打开手机,检查其中是否有
      .nomedia
      文件

      参见代码片段1

      -

    如果是的话,检查一下我是否能在里面找到一些图像文件

    参见代码片段2

    • 通过
      ContentResolver
      是不可能的,是吗

    是的


    我已上载了整个示例,您可以根据需要下载和修改

    此方法的问题在于速度。你需要得到一个文件夹的所有文件,这真的很慢。。。这是我目前的解决方案,通过一个小型性能优化(我从媒体商店查询所有可见文件夹,不检查可见文件夹,这是我迄今为止唯一能想到的优化)在内容解析的帮助下添加了另一个答案此方法可以搜索整个手机存储吗?如果是,请告诉我在
    @param dir
    中应该传递什么?读一下,我会测试一下,非常感谢。听起来真的很棒。不知道“.nomedia”文件是通过
    MediaStore
    索引和访问的……它不限于.nomedia文件。您可以以类似的方式找到所有pdf文件,只要将.nomedia替换为常数中的.pdf即可。我知道这一点。。。只是想一想,媒体商店根本没有索引隐藏的文件/文件夹……这仍然有一个巨大的问题:当使用存储提供商时,列出文件的速度非常慢(几乎不可用)。所以检查文件夹是否有即时消息
    /**
         * 
         * @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;
    
        }