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()