最近有个需求让板子MTP 接入PC后仅显示指定的一个文件,网上百度了下没有对应的文章。所以自己研究下做个总结。

    MTP,全称是Media Transfer Protocol(媒体传输协议)。它是微软的一个为计算机和便携式设备之间传输图像、音乐等所定制的协议。即从实现上理解为,服务端对自己的存储设备进行管控,为客户端提供存储设备上的数据查询、删除、创建等操作。对当前PC端来说,与实际操作安卓SD卡内容表现差不多;

  

  1. 框架大致介绍:

    Android中MTP的框架如下图所示:(ps:图片来源于网上)

android文件夹删除会打印什么系统日志 安卓 删除文件有误_MTP

     1、底层通过USB 进行通信,协议的监听解析与响应由上层提供。本次没有细研究JNI层的实现,仅查看下framework 层相关的实现;

     2、framework 层,MtpServer相当于一个服务器,与底层进行通信为其提供MTP的相关服务。MtpDatabase充当着数据库的功能,但它本身并没有数据库对数据进行保存,本质上是通过MediaProvider数据库获取所需要的数据。而本次的修改,也主要对MtpDatabase;


  2.修改实施:

        涉及文件:

        \frameworks\base\media\java\android\mtp\MtpDatabase.java

        1、MtpDatabase 做为数据库的功能,那么在MTP 协议内,需显示几个文件,文件名字格式等相关的东西应该应该就是从MtpDatabase内查询到的;那就针对MtpDatabase加了相关打印,确定了下大致的流程;

         先调用  private int[] getObjectList(int storageID, int format, int parent)  入参分辨为storageID (应该跟存储的设备相关)  format(格式?猜猜可能是可以区分音频视频图片之类的) parent(用以区分根目录还是子目录)  返回值为int的数组,数组个数应该就是表示有几个文件的意思,数组的内容,是数据库查询到的ID ,应该就是数据库内的排序关系;

       中间过程未去研究(如果要细研究的话,最好是能获取到MTP的通信流程。抓包最好, - - 但还没研究USB下能不能抓到包)

      在获取到int 的数据,应该是会遍历int 数组然后调用    private MtpPropertyList getObjectPropertyList(long handle, int format, long property,
                        int groupCode, int depth)  其中handle就是每个Int 的值,去获取对应每个文件的属性、名字等参数;

      2、大致了解到实现后就做了如下修改:

         a、修改createObjectQuery 内 查询数据库内容,需包含文件名信息;

        修改如下:



       b、在getPropertyList 内增加对查询的数据内容(数据内已增加文件名信息,getint(0)或者getString(1)函数的入参由createObjectQuery修改的PATH_PROJECTIONme宏排序决定)进行筛选,  仅返回需要的文件ID );



1、本次修改仅针对需求去理解,MTP的协议相关未做深入理解;如有有误的地方,欢迎拍砖;