文档章节

[MediaStore]小米文件管理器android版源码分析——数据来源

亭子happy
 亭子happy
发布于 2012/09/07 12:15
字数 614
阅读 7826
收藏 17

    打开小米的文件管理器,我们很快会看到如下图所示的界面:

其中,会把各种文件分类显示。并且显示出每种文件的个数。

这是怎么做到的呢?当然不是每次启动都查询sdcard和应用程序data目录文件啦,那样实在是太慢太愚蠢了。因为android框架的MediaStore已经为我们提供了相应的功能。对于各种类型的文件,都有一个ContentProvider提供相应的数据。我们需要通过正确的uri去查询相应的ContentProvider即可。

下面就从分析小米手机源码入手,看看是如何使用MediaStore的。

首先,以枚举的形式定义不同文件类型:

public enum FileCategory {
        All, Music, Video, Picture, Theme, Doc, Zip, Apk, Custom, Other, Favorite
    }

接着,设置各种文件查询的uri:

// query database
        String volumeName = "external";

        Uri uri = Audio.Media.getContentUri(volumeName);  //音频文件
        refreshMediaCategory(FileCategory.Music, uri);

        uri = Video.Media.getContentUri(volumeName);  //视频文件
        refreshMediaCategory(FileCategory.Video, uri);

        uri = Images.Media.getContentUri(volumeName);  //图片文件
        refreshMediaCategory(FileCategory.Picture, uri);

        uri = Files.getContentUri(volumeName);   //其他文件
        refreshMediaCategory(FileCategory.Theme, uri);
        refreshMediaCategory(FileCategory.Doc, uri);
        refreshMediaCategory(FileCategory.Zip, uri);
        refreshMediaCategory(FileCategory.Apk, uri);

其中,MediaStore.Files包含了除音频文件、视频文件、图片文件之外的其他文件类型。

之后,我们看refreshMediaCategory方法中做了什么事情:

private boolean refreshMediaCategory(FileCategory fc, Uri uri) {
        String[] columns = new String[] {
                "COUNT(*)", "SUM(_size)"
        };
        Cursor c = mContext.getContentResolver().query(uri, columns, buildSelectionByCategory(fc), null, null);
        if (c == null) {
            Log.e(LOG_TAG, "fail to query uri:" + uri);
            return false;
        }

        if (c.moveToNext()) {
            setCategoryInfo(fc, c.getLong(0), c.getLong(1));
            Log.v(LOG_TAG, "Retrieved " + fc.name() + " info >>> count:" + c.getLong(0) + " size:" + c.getLong(1));
            c.close();
            return true;
        }

        return false;
    }

这里面进行了对ContentProvider的查询,根据buildSelectionByCategory方法中设置的条件来查询。

再来看看buildSelectionByCategory方法中的内容:

private String buildSelectionByCategory(FileCategory cat) {
        String selection = null;
        switch (cat) {
            case Theme:
                selection = FileColumns.DATA + " LIKE '%.mtz'";
                break;
            case Doc:
                selection = buildDocSelection();
                break;
            case Zip:
                selection = "(" + FileColumns.MIME_TYPE + " == '" + Util.sZipFileMimeType + "')";
                break;
            case Apk:
                selection = FileColumns.DATA + " LIKE '%.apk'";
                break;
            default:
                selection = null;
        }
        return selection;
    }

因为只有MediaStore.Files中的文件内容需要区分,因此按条件查询只需要对这个进行即可。

对于压缩文件(Zip)是:

public static String sZipFileMimeType = "application/zip";

对于文档文件(Doc)是:

private String buildDocSelection() {
        StringBuilder selection = new StringBuilder();
        Iterator<String> iter = Util.sDocMimeTypesSet.iterator();
        while(iter.hasNext()) {
            selection.append("(" + FileColumns.MIME_TYPE + "=='" + iter.next() + "') OR ");
        }
        return  selection.substring(0, selection.lastIndexOf(")") + 1);
    }

其中,sDocMimeTypesSet是:

public static HashSet<String> sDocMimeTypesSet = new HashSet<String>() {
        {
            add("text/plain");
            add("text/plain");
            add("application/pdf");
            add("application/msword");
            add("application/vnd.ms-excel");
            add("application/vnd.ms-excel");
        }
    };

这样,我们就清楚了小米文件管理器是如何通过MediaStore的功能来实现很快找出各种类型的文件的了。

© 著作权归作者所有

亭子happy
粉丝 120
博文 238
码字总数 46521
作品 0
海淀
程序员
私信 提问
加载中

评论(8)

王高高
王高高
亭子happy
亭子happy 博主

引用来自“chinabird”的评论

能发一份源代码给我吗?或者是下载地址?我是个新学编程的人。GITHUB只听说过,不知道怎么用。麻烦发一份到1258818183@qq.com

github上的地址是:https://github.com/tingzi/FileExplorer,你可以直接在上面看源码的。
c
chinabird
能发一份源代码给我吗?或者是下载地址?我是个新学编程的人。GITHUB只听说过,不知道怎么用。麻烦发一份到1258818183@qq.com
c
chinabird
等等
亭子happy
亭子happy 博主

引用来自“金氧”的评论

引用来自“亭子happy”的评论

引用来自“金氧”的评论

请问哪里搞到的源代码?

github上

那个好老了,好长时间没更新维护了

我看的就是github上那个
金氧
金氧

引用来自“亭子happy”的评论

引用来自“金氧”的评论

请问哪里搞到的源代码?

github上

那个好老了,好长时间没更新维护了
亭子happy
亭子happy 博主

引用来自“金氧”的评论

请问哪里搞到的源代码?

github上
金氧
金氧
请问哪里搞到的源代码?
Android本地的Content Provider

Android本地的Content Provider Android 暴露了许多 Content Provider 来访问本地的数据库。 你可以使用之前描述的技巧来使用本地的 Content Provider 。可变通的地方, android.provider 类...

晨曦之光
2012/03/05
690
0
C语言自学完备手册(22)——输入输出

版权声明: https://blog.csdn.net/lfdfhl/article/details/82897916 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–o...

谷哥的小弟
2018/09/29
0
0
我扒了 6730 个微信用户数据,得出了这些结论......

作者 | NFii 责编 | 郭芮 本文给大家分享一篇从小程序用户使用网络、微信版本、手机型号、屏幕样式、微信字体大小等方面来分析大家的手机使用习惯。 技术分析 1、数据来源:微信小程序(英文...

CSDN资讯
2018/12/02
0
0
Android开源git40个App源码

(JamsMusicPlayer)很棒的音乐播放器(new) (F8)日程安排的软件 (Conversations)基于XMPP的应用 (Bitocle)可以在手机上查看自己github上的项目 (Amphitheatre)Android TV应用,数据来源于TMDb,...

拉偶有所依
2015/06/03
1K
2
MySQL数据库实操教程(34)——SQL语句综合练习

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 https://blog.csdn.net/lfdfhl/article/details/99702391 自定义View系列教程00–推翻自己和...

谷哥的小弟
08/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

kubernetes pod exec接口调用

正文 一般生产环境上由于网络安全策略,大多数端口是不能为集群外部访问的。多个集群之间一般都是通过k8s的ApiServer组件提供的接口通信,如https://192.168.1.101:6443。所以在做云平台时,...

码农实战
39分钟前
4
0
3_数组

3_数组

行者终成事
今天
8
0
经典系统设计面试题解析:如何设计TinyURL(二)

原文链接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
今天
7
0
使用logstash同步MySQL数据到ES

概述   在生成业务常有将MySQL数据同步到ES的需求,如果需要很高的定制化,往往需要开发同步程序用于处理数据。但没有特殊业务需求,官方提供的logstash就很有优势了。   在使用logstas...

zxiaofan666
今天
10
0
X-MSG-IM-分布式信令跟踪能力

经过一周多的鏖战, X-MSG-IM的分布式信令跟踪能力已基本具备, 特点是: 实时. 只有要RX/TX就会实时产生信令跟踪事件, 先入kafka, 再入influxdb待查. 同时提供实时sub/pub接口. 完备. 可以完整...

dev5
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部