自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MTP in Android詳解

移動開發(fā) Android
MTP的全稱是Media Transfer Protocol(媒體傳輸協(xié)議),它是微軟公司提出的一套媒體文件傳輸協(xié)議。Android從3.0開始支持MTP。不過,在今天的智能手機(jī)領(lǐng)域內(nèi),Google和微軟是一對冤家,為什么Android中會使用MTP呢?請看下文。

MTP的全稱是Media Transfer Protocol(媒體傳輸協(xié)議),它是微軟公司提出的一套媒體文件傳輸協(xié)議。Android從3.0開始支持MTP。

不過,在今天的智能手機(jī)領(lǐng)域內(nèi),Google和微軟是一對冤家,為什么Android中會使用MTP呢?請看下文。

 

 

一  背景知識介紹

筆者相信《程序員》雜志的絕大多數(shù)讀者或多或少都使用過MTP。因?yàn)樵缭谥悄苁謾C(jī)普及前,數(shù)碼相機(jī)和MP3播放器等都使用了MTP的前身PTP(Picture Transfer Protocol)進(jìn)行媒體文件傳輸。那時,只要通過USB數(shù)據(jù)線把它們連接上Windows操作系統(tǒng),就能在“我的電腦“中見到這些設(shè)備了。此后,用戶可以把它們當(dāng)做U盤一樣使用,例如對其進(jìn)行目錄、文件的瀏覽和拷貝等操作。

既然可以通過MTP把智能設(shè)備當(dāng)作U盤使用,那么它和我們常用的USB大容量存儲(USB Mass Storage,簡稱UMS)有何不同呢?

  • UMS模式下,PC操作存儲設(shè)備的粒度是設(shè)備塊(FAT block),而非文件系統(tǒng)。什么意思?此處舉一個簡單例子。當(dāng)Android手機(jī)通過UMS將sdcard掛載到PC后,PC就擁有對sdcard的絕對控制權(quán)。這樣,手機(jī)就無法同時訪問sdcard了。這種做法帶來的后果就是Camera或Music程序?qū)⒁驔]有外部存儲空間而提示無法進(jìn)行操作(注意,有些廠商的手機(jī)對此進(jìn)行過修改,使得Camera能短時間錄制一部分視頻到內(nèi)部存儲空間)。這也是Android早期版本中一個很明顯的特點(diǎn)。另外,由于PC在操作sdcard時可能弄壞其文件系統(tǒng),這將導(dǎo)致sdcard重新掛載到手機(jī)后不能被識別。
  • 如果Android手機(jī)的sdcard以MTP模式掛載到PC機(jī)上,sdcard的控制權(quán)其實(shí)還是屬于手機(jī)。只不過智能手機(jī)通過MTP協(xié)議向PC機(jī)構(gòu)建了一個虛擬文件系統(tǒng)。PC機(jī)操作其中的文件時,都會通過標(biāo)準(zhǔn)MTP協(xié)議向智能手機(jī)發(fā)起請求。另外,Android把MTP功能集成在MediaProvider中,其好處是PC機(jī)操作(例如拷貝或刪除等)媒體文件時,媒體數(shù)據(jù)都會及時更新到媒體數(shù)據(jù)庫中。而UMS模式下,當(dāng)sdcard掛載回手機(jī)后,Android還得花較長時間重新掃描媒體文件以更新媒體數(shù)據(jù)庫。

MTP的好處還有很多,例如它可判斷PC機(jī)拷貝的媒體文件是否受目標(biāo)手機(jī)支持,甚至可以觸發(fā)對應(yīng)的轉(zhuǎn)碼程序?qū)⑵滢D(zhuǎn)換成手機(jī)支持的格式。不過和UMS相比,MTP也有不足之處:

  • 傳輸大文件的速度較慢。
  • MTP不能直接修改文件本身。只能先拷貝到本地修改,完畢后再拷貝回去。
  • 除了Windows外,Linux和MacOS對MTP支持還不是很完善。

下面我們將介紹MTP協(xié)議。

1.1  MTP協(xié)議介紹

根據(jù)協(xié)議,MTP的使用者包括兩個部分,分別是Initiator和Responder。如圖1-1所示:

圖1-1  Initiator和Responder圖示

由圖1-1可知:

  • Initiator:主要是指USB Host,例如PC機(jī),筆記本等。協(xié)議規(guī)定所有MTP操作只能由Initator發(fā)起。
  • Responder:一般是諸如數(shù)碼相機(jī)、智能手機(jī)等存儲媒體文件的設(shè)備。Responder在MTP中的作用就是處理Initator發(fā)起的請求。同時,它還會根據(jù)自身狀態(tài)的變化發(fā)送Event以通知Initiator。

注意:后文我們將統(tǒng)一以PC代表Initiator,Android手機(jī)代表Responder。

與很多協(xié)議一樣,MTP也有自己的協(xié)議棧,如圖1-2所示:

圖1-2  MTP協(xié)議棧

由圖1-2可知,MTP協(xié)議棧由下到上分別是:

  • Pyshical Layer(物理層):物理層在MTP協(xié)議中用來傳輸數(shù)據(jù)。目前有三種物理層可供MTP使用。它們分別是USB:其主要特點(diǎn)是傳輸文件,同步媒體文件時速度快,而且可以邊工作邊充電,這是目前用的最多的一種方式;IP:基于IP的MTP(簡稱MTP/IP)將通過UPnP來匹配和發(fā)現(xiàn)設(shè)備。它是家庭網(wǎng)絡(luò)中是最理想的傳輸方式;Bluetooth:MTP/BT是最省電,同時也是速度最慢的一種傳輸方式,用處較少。
  • 傳輸層:MTP中,數(shù)據(jù)傳輸格式遵循PTP協(xié)議
  • 命令層:實(shí)現(xiàn)了MTP協(xié)議中的各種命令。

如上文所述,MTP采用命令-應(yīng)答方式來工作(Initator發(fā)送命令給Responder處理,Responser反饋處理結(jié)果),這種方式的主要特點(diǎn)有:

  • 所有MTP命令均以Package(數(shù)據(jù)包)的方式在設(shè)備兩端進(jìn)行傳遞。
  • Initiator必須接收到前一條消息的處理結(jié)果(不論是成功還是超時)后,才能發(fā)送下一條消息。

下面我們將以PC通過MTP打開一個文件為例,按順序介紹其中涉及到幾個主要MTP命令:

  • 當(dāng)設(shè)備***次連接上PC后,Initiator(即PC)首先會發(fā)送一個名為GetDeviceInfo的請求以獲取設(shè)備的信息,這些信息包括設(shè)備所支持PTP版本的程度,以百分號表示(默認(rèn)是100)、所支持的MTP命令(Operation Supported)、所支持的Event類型等。
  • 接著PC端會發(fā)送OpenSession命令以創(chuàng)建一個會話,該會話一直保持到設(shè)備從PC上斷開為止。此后所有命令(除GetDeviceInfo命令外)必須在此會話存活期間才能發(fā)送。會話在MTP協(xié)議中由SessionID來標(biāo)識,它是一個32位的無符號整型,由PC選擇并傳給手機(jī)。
  • PC端如果要進(jìn)行文件操作的話,必須從根目錄開始定位目標(biāo)文件。由于Windows的特殊性,手機(jī)內(nèi)部存儲卡在windows系統(tǒng)中顯示為盤符。注意,如果手機(jī)內(nèi)部有兩塊存儲卡的話(如內(nèi)部存儲卡和外部sd卡),Windows中會顯示為兩個盤符。PC端需要通過GetStorageIDs命令返回某個盤符對應(yīng)的StorageID。在MTP中,StorageID是一個32位無符號整型,每一個StorageID代表了一個邏輯盤符。
  • PC端可以根據(jù)上一步的StorageID號,利用GetStorageInfo操作去獲取存儲設(shè)備的信息,例如剩余存儲空間、文件系統(tǒng)類型、訪問權(quán)限等。
  • 接著,PC就會通過GetObjectHandles命令來獲取此盤符下的文件和子目錄的Object Handles(一個Object Handle代表一個文件或目錄。該值由Responder生成并保證唯一性)。有了Object Handle,PC就可以操作這些文件或目錄了,例如繼續(xù)通過GetObjectHandles獲取某個目錄中子文件和子目錄的信息。
  • 假設(shè)現(xiàn)在需拷貝一個文件到手機(jī)上,那么PC會通過SendObjectInfo命令將文件信息(如文件名、文件大?。┑葌鬟f給手機(jī)。而手機(jī)需要檢查目標(biāo)目錄是否有足夠的空間和對應(yīng)權(quán)限。
  • 如果一切正常,PC將通過SendObject把數(shù)據(jù)傳遞給手機(jī)。真正寫文件到設(shè)備存儲空間的則是手機(jī)中的Responder。Android實(shí)現(xiàn)的MTP還會在媒體文件傳輸完畢后,將信息更新到媒體數(shù)據(jù)庫中。
  • 除此之外,PC還可利用SetObjectPropValue 命令來設(shè)置文件的各種屬性值,如Audio BitRate(比特率),Sample Rate(采樣率),Number Of Channels(聲道)等。

以上為讀者描述了MTP使用的一個簡單案例。至于其中的各種MTP命令,讀者不妨閱讀參考文獻(xiàn)1,即《MTP Specification v1.0.pdf》。協(xié)議對各種命令都有非常精確的描述,例如表1-1,表1-2所示為GetDeviceInfo命令,返回值定義。其參數(shù)類型,傳遞方向都有詳細(xì)解釋(不得不說,和Linux比起來,微軟的開發(fā)/技術(shù)文檔做得相當(dāng)?shù)轿唬?/p>

表1-1  GetDeviceInfo命令定義

Operation Code

0x1001

GetDeviceInfo對應(yīng)命令的數(shù)字編號是0x1001

Data

DeviceInfo dataset

手機(jī)端返回的設(shè)備信息數(shù)據(jù)集

Data Direction

R->I

數(shù)據(jù)傳輸方向是手機(jī)到PC

ResponseCode Options

OK, Parameter_Not_Supported

手機(jī)給PC的返回值

表1-2所示為GetDeviceInfo的返回?cái)?shù)據(jù)集的定義。

表1-2  GetDeviceInfo返回?cái)?shù)據(jù)集的定義

Dataset field

Field order

Size (bytes)

Datatype

Comments

Standard Version

1

2

UINT16

手機(jī)對PTP協(xié)議的支持程度,以%表示,默認(rèn)是100

MTP Vendor Extension ID

2

4

UINT32

手機(jī)對PTP廠商擴(kuò)展協(xié)議的支持,默認(rèn)是0xFFFFFFFF

MTP Version

3

2

UINT16

手機(jī)支持的MTP標(biāo)準(zhǔn)的版本,以%表示

MTP Extensions

4

Variable

String

手機(jī)支持的MTP擴(kuò)展集

Functional Mode

5

2

UINT16

手機(jī)允許的模式

Operations Supported

6

Variable

Operation Code Array

在當(dāng)前功能模式下,手機(jī)支持的所有操作

Event Supported

7

Variable

Event Code Array

在當(dāng)前功能模式下,手機(jī)能產(chǎn)生的所有事件

Device Properties Supported

8

Variable

Device Property Code Array

在當(dāng)前功能模式下,手機(jī)支持的所有設(shè)備屬性

Capture Formats

9

Variable

Object Format Code Array

手機(jī)可以自己生成的文件格式,不包括拷貝到手機(jī)上文件格式

Playback Formats

10

Variable

Object Format Code Array

手機(jī)可以解析和理解的所有格式類型

Manufacturer

11

Variable

String

人可讀的手機(jī)制造商的標(biāo)識

Model

12

Variable

String

人可讀的手機(jī)型號

Device Version

13

Variable

String

手機(jī)的軟件或固件版本

Serial Number

14

Variable

String

能標(biāo)明手機(jī)MTP功能的唯一序列號

 

1.2  OS對MTP的支持及認(rèn)證

MTP協(xié)議既然由微軟提出,理所當(dāng)然,Windows對其支持自然是不遺余力。目前Windows操作系統(tǒng)中,MTP和多媒體框架緊密結(jié)合,并且已經(jīng)成為Windows Media框架中的重要一部分。如WMP10(Windows Media Player 10)和WMP11均內(nèi)置對MTP功能,其中WMP11還新增對Playlist和Album art的支持。

微軟除了提出MTP協(xié)議并在Windows操作系統(tǒng)中提供大力支持外,它對使用MTP協(xié)議的設(shè)備也有所管理。所有標(biāo)稱支持MTP協(xié)議的設(shè)備,必須通過微軟的測試WLK(Windows Logo Kit)。WLK測試通過的設(shè)備可以獲得一個徽標(biāo)。關(guān)于WLK測試的詳細(xì)信息,請讀者參考http://msdn.microsoft.com/zh-cn/library/windows/hardware/gg487530.aspx。從以上鏈接中也能下載到wpdmon,它是MTP開發(fā)中最常用的測試工具,可顯示出所有PC與手機(jī)進(jìn)行MTP操作時發(fā)送的命令、數(shù)據(jù)及返回值。圖1-3為筆者測試某臺Android手機(jī)的MTP功能時用wpdmon截獲的信息示意圖:

圖1-3  wpdmon工具使用示意圖

下面我們來看MTP在Android平臺中的實(shí)現(xiàn)。

#p#

二  Android中的MTP

Android從3.0開始集成MTP功能,主要原因有三個:

  • 手機(jī)要支持UMS的話,必須有一個sd卡,因?yàn)閟d卡往往采用Windows支持的分區(qū)格式。如果想把內(nèi)部存儲空間通過UMS掛載到Windows上,則內(nèi)部存儲空間需采用特定的分區(qū)格式。這對某些手機(jī)而言根本不可行。因?yàn)閮?nèi)部存儲空間本身可能是一個設(shè)備,它們采用統(tǒng)一的分區(qū)格式。不能因?yàn)樾枰褂肬MS,而再增加一塊特定分區(qū)格式的存儲設(shè)備。
  • UMS掛載到PC后,PC操作系統(tǒng)擁有絕對控制權(quán)。此時,Android系統(tǒng)將無法操作這些設(shè)備。根據(jù)前文舉的Camera例子而言,這對越來越高級的Android版本而言是不可接受的。
  • 另外一個不可忽略的事實(shí)就是Windows操作系統(tǒng)在普通勞動人民那兒依然占據(jù)極高的市場份額。這恐怕也是明知Linux、MacOS對MTP支持力度不夠,Android也要集成它的一個重要原因吧。

2.1  Android中MTP的代碼架構(gòu)

要使用MTP功能,首先需要在設(shè)置中啟用USB連接模式為MTP,如圖1-4所示:

圖1-4  Settings中的MTP設(shè)置

圖1-4所示為參考機(jī)(Android 4.1版本)中“USB連接模式”設(shè)置。該操作實(shí)際上會觸發(fā)USB驅(qū)動做相應(yīng)變動。本文不擬討論其中的過程,讀者可參考手機(jī)中init.platform-name.usb.rc文件以查看Android系統(tǒng)中USB的模式設(shè)置。從目前市面上發(fā)布的數(shù)款A(yù)ndroid 4.0及后續(xù)版本的機(jī)型來看,MTP/PTP大有取代UMS的趨勢。

根據(jù)前文所述,Android中的MTP和已有的MediaProvider模塊結(jié)合緊密,以更好體現(xiàn)“Media Transfer”的特性。其主要結(jié)構(gòu)如圖1-5所示:

圖1-5  Android MTP架構(gòu)圖

由圖1-5可知,Android MTP架構(gòu)由下到上分別是:

  • C++層包括幾個主要對象,如MtpRequestPacke負(fù)責(zé)從USB驅(qū)動讀取數(shù)據(jù),并結(jié)構(gòu)化命令格式及其參數(shù)、MtpDataPacket負(fù)責(zé)結(jié)構(gòu)化手機(jī)要返回給PC的數(shù)據(jù)包、MtpResponsePacket負(fù)責(zé)結(jié)構(gòu)化手機(jī)要給PC返回的response。MtpServer負(fù)責(zé)解析來自PC的命令并調(diào)用相應(yīng)的接口函數(shù)進(jìn)行處理。
  • Java層包括UsbReceiver、MtpService、MtpServer等對象。其中UsbReceiver用來監(jiān)視USB事件,判斷何時啟動或停止MtpService。MtpService負(fù)責(zé)啟動MtpServer和加載存儲設(shè)備的信息到數(shù)據(jù)庫。MtpServer負(fù)責(zé)通過jni接口去啟動/停止C++層中MtpServer以及處理Storage的添加和刪除。MediaProvider則負(fù)責(zé)查詢和更新數(shù)據(jù)庫。MtpDatabase名字雖然叫Database,但實(shí)際功能用于在MediaProvider和MtpServer之間轉(zhuǎn)換數(shù)據(jù)格式。例如把MTP傳遞過來的信息(如文件大小、文件路徑等)轉(zhuǎn)換成MediaProvider需要的格式以方便其更新數(shù)據(jù)庫。

下面我們來看MTP的工作流程。

2.2  MTP流程分析

我們先來看MTP模塊啟動的流程,如圖1-6所示:

圖1-6  MTP主要模塊啟動流程

由圖1-6可知:

  • 當(dāng)手機(jī)連上usb線后,UsbReceiver會收到來自系統(tǒng)的USB_STATE廣播事件。接著它需要從UsbManager中查詢USB的鏈接狀態(tài),MTP的設(shè)置信息和PTP的設(shè)置信息。當(dāng)用戶設(shè)置為使用MTP模式時,UsbReceiver將通過startService函數(shù)啟動MtpService。
  • MtpService啟動,在其onStartCommand中將創(chuàng)建MtpDatabase對象和MtpServer對象。
  • UsbReceiver同時通過insert一條特殊uri(值為“content://media/none/mtp_connected”)的方式,觸發(fā)MdiaProvder調(diào)用MtpService的bindService函數(shù)。這樣,MediaProvider和MtpService就建立了緊密聯(lián)系。

MtpServer是Android平臺中MTP協(xié)議處理的核心模塊,它會單獨(dú)啟動一個線程用于接收PC端的命令,其代碼如圖1-7所示:

圖1-7  MtpServer run函數(shù)代碼片段

由圖1-7可知,MtpServer不斷從文件描述符讀取請求,然后調(diào)用handleRequest進(jìn)行處理。***把處理結(jié)果返回給對端。

從這段代碼讀者可以發(fā)現(xiàn),Android MTP命令層和物理層之間的耦合度較低,這樣也方便將來實(shí)現(xiàn)MTP/IP功能。

接下來我們看看PC端發(fā)送SendObjectInfo的處理流程,如圖1-8所示:

圖1-8  sendObjectInfo處理流程圖

由圖1-8可知SendObjectInfo的處理流程大體步驟如下:

  • PC發(fā)SendObjectInfo命令給MtpServer。MtpServer需要檢查存儲設(shè)備剩余空間、可支持的***文件大小。如果一切正常的話,它會通過MediaProvider的insert函數(shù)往媒體數(shù)據(jù)庫中加入一條數(shù)據(jù)項(xiàng)。
  • 接著PC通過SendObject將文件內(nèi)容傳遞給給MtpServer。而MtpServer就會創(chuàng)建該文件,并把數(shù)據(jù)寫到文件中。
  • 當(dāng)文件數(shù)據(jù)發(fā)送完畢,MtpServer調(diào)用endSendObject。而endObject則會觸發(fā)MediaScanner進(jìn)行媒體文件掃描。當(dāng)然,掃描完后,該文件攜帶的媒體信息(假如是MP3文件的話,則會把專輯信息、歌手、流派、長度等內(nèi)容)加入到媒體數(shù)據(jù)庫中。

通過對SendObjectInfo描述,我們也可看出,Android充分利用了其平臺本身的特性,真正將媒體傳輸協(xié)議和媒體文件掃描恰到好處得結(jié)合起來,從而發(fā)揮了MTP***功效。

三  總結(jié)

本文主要對Android中的MTP進(jìn)行了相關(guān)介紹。雖然MTP協(xié)議由微軟提供,但因?yàn)闅v史原因,其使用程度相當(dāng)廣泛,以至于Android也提供了最基本的MTP實(shí)現(xiàn)。

當(dāng)然,如果要做到真正實(shí)用并通過微軟認(rèn)證,手機(jī)廠商還需要在此基礎(chǔ)上做進(jìn)一步的開發(fā)。結(jié)合筆者自己的使用經(jīng)歷,國外大牌手機(jī)廠商例如Sony、Samsung、Nokia等對MTP的支持相當(dāng)?shù)轿?。相比而言,國?nèi)手機(jī)廠商的起步稍微晚一點(diǎn),需要投入更多的精力才能超越。另外,隨著無線技術(shù)的普及,MTP基于IP的實(shí)現(xiàn)也將極大方面用戶的使用。筆者在此希望大家能一起努力,早日讓用戶從USB數(shù)據(jù)線中解放出來。

責(zé)任編輯:張葉青 來源: 博客園
相關(guān)推薦

2015-03-10 10:53:29

2014-07-28 10:09:30

Android

2011-05-27 15:02:15

Android ListView

2014-07-24 09:11:34

2017-01-11 19:05:45

AndroidAndroid Loa詳解

2013-11-14 16:50:08

2013-12-25 09:34:26

Android SDKAndroid組件

2021-09-07 08:49:35

Android

2010-07-13 09:02:19

Widget開發(fā)

2013-01-11 13:48:41

Android開發(fā)組件Notificatio

2011-09-09 20:14:58

Android Wid

2013-01-10 14:39:28

Android開發(fā)Content Pro組件

2013-01-05 09:21:55

Ubuntu for UbuntuAndroid

2010-01-28 14:07:59

Android Ale

2010-02-03 15:59:08

Android組件

2009-11-30 16:38:30

Android

2011-05-31 09:36:46

Android 布局屬性

2011-09-09 16:23:16

Android Web測試

2011-09-07 13:18:40

Android Wid

2011-09-14 09:40:06

Android開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號