MTP in Android详解java
最近好长一段时间没有作笔记了,今天主要学习一下MTP相关的知识。程序员
MTP的全称是Media Transfer Protocol(媒体传输协议),它是微软公司提出的一套媒体文件传输协议。Android从3.0开始支持MTP。数据库
笔者相信《程序员》杂志的绝大多数读者或多或少都使用过MTP。由于早在智能手机普及前,数码相机和MP3播放器等都使用了MTP的前身PTP(Picture Transfer Protocol)进行媒体文件传输。那时,只要经过USB数据线把它们链接上Windows操做系统,就能在“个人电脑“中见到这些设备了。此后,用户能够把它们当作U盘同样使用,例如对其进行目录、文件的浏览和拷贝等操做。windows
既然能够经过MTP把智能设备看成U盘使用,那么它和咱们经常使用的USB大容量存储(USB Mass Storage,简称UMS)有何不一样呢?网络
MTP的好处还有不少,例如它可判断PC机拷贝的媒体文件是否受目标手机支持,甚至能够触发对应的转码程序将其转换成手机支持的格式。不过和UMS相比,MTP也有不足之处:架构
下面咱们将介绍MTP协议。框架
根据协议,MTP的使用者包括两个部分,分别是Initiator和Responder。如图1-1所示:ide
图1-1 Initiator和Responder图示函数
由图1-1可知:工具
注意:后文咱们将统一以PC表明Initiator,Android手机表明Responder。
与不少协议同样,MTP也有本身的协议栈,如图1-2所示:
图1-2 MTP协议栈
由图1-2可知,MTP协议栈由下到上分别是:
如上文所述,MTP采用命令-应答方式来工做(Initator发送命令给Responder处理,Responser反馈处理结果),这种方式的主要特色有:
下面咱们将以PC经过MTP打开一个文件为例,按顺序介绍其中涉及到几个主要MTP命令:
以上为读者描述了MTP使用的一个简单案例。至于其中的各类MTP命令,读者不妨阅读参考文献1,即《MTP Specification v1.0.pdf》。协议对各类命令都有很是精确的描述,例如表1-1,表1-2所示为GetDeviceInfo命令,返回值定义。其参数类型,传递方向都有详细解释(不得不说,和Linux比起来,微软的开发/技术文档作得至关到位)。
表1-1 GetDeviceInfo命令定义
Operation Code |
0x1001 |
GetDeviceInfo对应命令的数字编号是0x1001 |
Data |
DeviceInfo dataset |
手机端返回的设备信息数据集 |
Data Direction |
R->I |
数据传输方向是手机到PC |
ResponseCode Options |
OK, Parameter_Not_Supported |
手机给PC的返回值 |
表1-2所示为GetDeviceInfo的返回数据集的定义。
表1-2 GetDeviceInfo返回数据集的定义
Dataset field |
Field order |
Size (bytes) |
Datatype |
Comments |
Standard Version |
1 |
2 |
UINT16 |
手机对PTP协议的支持程度,以%表示,默认是100 |
MTP Vendor Extension ID |
2 |
4 |
UINT32 |
手机对PTP厂商扩展协议的支持,默认是0xFFFFFFFF |
MTP Version |
3 |
2 |
UINT16 |
手机支持的MTP标准的版本,以%表示 |
MTP Extensions |
4 |
Variable |
String |
手机支持的MTP扩展集 |
Functional Mode |
5 |
2 |
UINT16 |
手机容许的模式 |
Operations Supported |
6 |
Variable |
Operation Code Array |
在当前功能模式下,手机支持的全部操做 |
Event Supported |
7 |
Variable |
Event Code Array |
在当前功能模式下,手机能产生的全部事件 |
Device Properties Supported |
8 |
Variable |
Device Property Code Array |
在当前功能模式下,手机支持的全部设备属性 |
Capture Formats |
9 |
Variable |
Object Format Code Array |
手机能够本身生成的文件格式,不包括拷贝到手机上文件格式 |
Playback Formats |
10 |
Variable |
Object Format Code Array |
手机能够解析和理解的全部格式类型 |
Manufacturer |
11 |
Variable |
String |
人可读的手机制造商的标识 |
Model |
12 |
Variable |
String |
人可读的手机型号 |
Device Version |
13 |
Variable |
String |
手机的软件或固件版本 |
Serial Number |
14 |
Variable |
String |
能标明手机MTP功能的惟一序列号 |
MTP协议既然由微软提出,理所固然,Windows对其支持天然是竭尽全力。目前Windows操做系统中,MTP和多媒体框架紧密结合,而且已经成为Windows Media框架中的重要一部分。如WMP10(Windows Media Player 10)和WMP11均内置对MTP功能,其中WMP11还新增对Playlist和Album art的支持。
微软除了提出MTP协议并在Windows操做系统中提供大力支持外,它对使用MTP协议的设备也有所管理。全部标称支持MTP协议的设备,必须经过微软的测试WLK(Windows Logo Kit)。WLK测试经过的设备能够得到一个徽标。关于WLK测试的详细信息,请读者参考http://msdn.microsoft.com/zh-cn/library/windows/hardware/gg487530.aspx。从以上连接中也能下载到wpdmon,它是MTP开发中最经常使用的测试工具,可显示出全部PC与手机进行MTP操做时发送的命令、数据及返回值。图1-3为笔者测试某台Android手机的MTP功能时用wpdmon截获的信息示意图:
图1-3 wpdmon工具使用示意图
下面咱们来看MTP在Android平台中的实现。
Android从3.0开始集成MTP功能,主要缘由有三个:
要使用MTP功能,首先须要在设置中启用USB链接模式为MTP,如图1-4所示:
图1-4 Settings中的MTP设置
图1-4所示为参考机(Android 4.1版本)中“USB链接模式”设置。该操做实际上会触发USB驱动作相应变更。本文不拟讨论其中的过程,读者可参考手机中init.platform-name.usb.rc文件以查看Android系统中USB的模式设置。从目前市面上发布的数款Android 4.0及后续版本的机型来看,MTP/PTP大有取代UMS的趋势。
根据前文所述,Android中的MTP和已有的MediaProvider模块结合紧密,以更好体现“Media Transfer”的特性。其主要结构如图1-5所示:
图1-5 Android MTP架构图
由图1-5可知,Android MTP架构由下到上分别是:
下面咱们来看MTP的工做流程。
咱们先来看MTP模块启动的流程,如图1-6所示:
图1-6 MTP主要模块启动流程
由图1-6可知:
MtpServer是Android平台中MTP协议处理的核心模块,它会单独启动一个线程用于接收PC端的命令,其代码如图1-7所示:
图1-7 MtpServer run函数代码片断
由图1-7可知,MtpServer不断从文件描述符读取请求,而后调用handleRequest进行处理。最后把处理结果返回给对端。
从这段代码读者能够发现,Android MTP命令层和物理层之间的耦合度较低,这样也方便未来实现MTP/IP功能。
接下来咱们看看PC端发送SendObjectInfo的处理流程,如图1-8所示:
图1-8 sendObjectInfo处理流程图
由图1-8可知SendObjectInfo的处理流程大致步骤以下:
经过对SendObjectInfo描述,咱们也可看出,Android充分利用了其平台自己的特性,真正将媒体传输协议和媒体文件扫描恰到好处得结合起来,从而发挥了MTP最大功效。
本文主要对Android中的MTP进行了相关介绍。虽然MTP协议由微软提供,但由于历史缘由,其使用程度至关普遍,以致于Android也提供了最基本的MTP实现。
当 然,若是要作到真正实用并经过微软认证,手机厂商还须要在此基础上作进一步的开发。结合笔者本身的使用经历,国外大牌手机厂商例如Sony、 Samsung、Nokia等对MTP的支持至关到位。相比而言,国内手机厂商的起步稍微晚一点,须要投入更多的精力才能超越。另外,随着无线技术的普 及,MTP基于IP的实现也将极大方面用户的使用。笔者在此但愿你们能一块儿努力,早日让用户从USB数据线中解放出来。
我的以为主要把握两个流程:
1.java层向.cpp层流程,即命令层--->传输层
主要涉及流程为:UsbReceiver --> MtpService --> MediaProvider --> MtpDatabase --> MtpServer(MTP核心)
2. .c驱动层向.cpp层流程,即物理层-->传输层-->命令层
主要涉及流程为:UsbDriverSide --------> MtpServer --->MtpStorage --> MtpDatabase --> MediaProvider -->MediaScaner
SendObjectInfo() beginSendObject() insert()
SendObject() endSendObject() scanMtpFile()