Android提供復(fù)制和粘貼功能強(qiáng)大的基于剪貼板的框架。它支持簡單和復(fù)雜的數(shù)據(jù)類型,包括文本串,復(fù)雜的數(shù)據(jù)結(jié)構(gòu),文本和二進(jìn)制數(shù)據(jù)流,甚至應(yīng)用的資產(chǎn)。簡單的文本數(shù)據(jù)被直接存儲(chǔ)在剪貼板中,而復(fù)雜的數(shù)據(jù)被存儲(chǔ)作為該粘貼應(yīng)用程序與內(nèi)容提供商解析的引用。復(fù)制和粘貼都在應(yīng)用程序中,并實(shí)現(xiàn)了框架的應(yīng)用程序之間進(jìn)行。
由于框架的一部分使用內(nèi)容提供商,這個(gè)主題假定一些熟悉Android的內(nèi)容提供商的API,這是在主題中介紹
的內(nèi)容提供商。
剪貼板框架
當(dāng)您使用剪貼板框架,你把數(shù)據(jù)轉(zhuǎn)化為剪輯對象,然后把剪輯對象在全系統(tǒng)剪貼板。剪輯對象可以采取三種形式:
- 文本
-
文本字符串。您可以直接把串入剪輯對象,您然后將復(fù)制到剪貼板。要粘貼字符串,將剪貼板中的剪輯對象和字符串復(fù)制到您的應(yīng)用程序的存儲(chǔ)。
- URI
-
一個(gè)
開放的 代表任何形式的URI的對象。這主要是用于從內(nèi)容提供者復(fù)制復(fù)雜的數(shù)據(jù)。要復(fù)制的數(shù)據(jù),你把一個(gè)
開放的 對象轉(zhuǎn)換為剪輯對象,并把剪輯對象復(fù)制到剪貼板。要粘貼數(shù)據(jù),你得到的剪輯對象,得到
的Uri 對象,它解析為數(shù)據(jù)源,如內(nèi)容提供商,以及從源頭到應(yīng)用程序的存儲(chǔ)復(fù)制數(shù)據(jù)。
- 意圖
-
一個(gè)
意圖 。這支持復(fù)制應(yīng)用程序快捷方式。要復(fù)制的數(shù)據(jù),創(chuàng)建一個(gè)意圖,把它變成一個(gè)剪輯對象,并把剪輯對象復(fù)制到剪貼板。要粘貼數(shù)據(jù),你得到的剪輯對象,然后意圖對象復(fù)制到你的應(yīng)用程序的內(nèi)存區(qū)域。
剪貼板只擁有一次剪輯對象。當(dāng)應(yīng)用程序?qū)⒁粋€(gè)剪輯對象在剪貼板上,以前的剪輯對象消失。
如果你希望允許用戶將數(shù)據(jù)粘貼到你的應(yīng)用程序,你不必處理所有類型的數(shù)據(jù)。給你的用戶將其粘貼選項(xiàng)之前,您可以檢查剪貼板上的數(shù)據(jù)。除了具有一定的數(shù)據(jù)格式,剪輯對象也包含了告訴你什么MIME類型或類型可用的元數(shù)據(jù)。該元數(shù)據(jù)可以幫助你決定??是否你的應(yīng)用程序可以做一些與剪貼板數(shù)據(jù)非常有用。例如,如果你有一個(gè)應(yīng)用程序,主要處理可能要忽略包含URI或意圖剪輯對象的文本。
您也可以允許用戶將文本粘貼無論在剪貼板上的數(shù)據(jù)的形式。要做到這一點(diǎn),您可以強(qiáng)制剪貼板數(shù)據(jù)轉(zhuǎn)換成文本表示,然后粘貼這個(gè)文本。這是一節(jié)中所述強(qiáng)制轉(zhuǎn)換剪貼板文本。
剪貼板類
本節(jié)介紹剪貼板框架使用的類。
ClipboardManager
在Android系統(tǒng)中,系統(tǒng)剪貼板是由全球代表
ClipboardManager 類。您不要直接實(shí)例化這個(gè)類; 相反,你會(huì)得到通過調(diào)用它的一個(gè)引用
getSystemService(CLIPBOARD_SERVICE) 。
ClipData,ClipData.Item和ClipDesc??ription
將數(shù)據(jù)添加到剪貼板中,您可以創(chuàng)建一個(gè)ClipData 同時(shí)包含數(shù)據(jù)的描述和數(shù)據(jù)本身的對象。剪貼板僅容納一個(gè)
ClipData 一次。一個(gè)ClipData 包含
ClipDescription 對象和一個(gè)或多個(gè)
ClipData.Item 對象。
一個(gè)ClipDescription 對象包含有關(guān)片段元數(shù)據(jù)。尤其是,它含有可用MIME類型的片段的數(shù)據(jù)數(shù)組。當(dāng)你把一個(gè)剪輯在剪貼板,這個(gè)數(shù)組可用于粘貼的應(yīng)用程序,它可以檢查它,看看他們是否可以處理任何可用的MIME類型。
一個(gè)ClipData.Item 對象包含文本,URI或意向數(shù)據(jù):
- 文本
-
一個(gè)
CharSequence的 。
- URI
-
一個(gè)
開放的 。這通常包含的內(nèi)容提供者的URI,盡管任何URI被允許的。提供數(shù)據(jù)的應(yīng)用程序?qū)RI剪貼板上。希望粘貼數(shù)據(jù)的應(yīng)用程序從剪貼板中得到URI并用它來 ??訪問內(nèi)容提供商(或其他數(shù)據(jù)源)和檢索數(shù)據(jù)。
- 意圖
-
一個(gè)
意圖 。此數(shù)據(jù)類型可以讓你的應(yīng)用程序快捷方式復(fù)制到剪貼板。然后,用戶可以粘貼快捷方式到他們的應(yīng)用程序供以后使用。
您可以添加多個(gè)ClipData.Item 到剪輯對象。這允許用戶多重選擇作為一個(gè)剪輯復(fù)制和粘貼。例如,如果你有一個(gè)列表小工具,允許用戶同時(shí)選擇多個(gè)項(xiàng)目,可以將所有的項(xiàng)目一次復(fù)制到剪貼板。要做到這一點(diǎn),您可以創(chuàng)建一個(gè)單獨(dú)的
ClipData.Item 每個(gè)列表項(xiàng),然后你添加
ClipData.Item 對象的ClipData 對象。
ClipData方便的方法
該ClipData 類為創(chuàng)建靜態(tài)便捷方法ClipData 與單個(gè)對象ClipData.Item
對象和一個(gè)簡單的ClipDescription 對象:
-
newPlainText(標(biāo)簽,文本)
-
返回
ClipData 對象,其單
ClipData.Item 對象包含的文本字符串。該
ClipDescription 對象的標(biāo)簽設(shè)置標(biāo)簽 。在單MIME類型ClipDescription 是
MIMETYPE_TEXT_PLAIN 。
使用
newPlainText()
來創(chuàng)建一個(gè)文本字符串的剪輯。
-
newUri(解析器,標(biāo)簽,URI)
-
返回
ClipData 對象,其單
ClipData.Item 對象包含一個(gè)URI。該
ClipDescription 對象的標(biāo)簽設(shè)置標(biāo)簽 。如果URI是內(nèi)容的URI(Uri.getScheme() 返回
內(nèi)容: ),該方法使用的ContentResolver的 中提供的對象分解器 ,從內(nèi)容提供商檢索可用的MIME類型,并將它們存儲(chǔ)在ClipDescription 。對于一個(gè)URI不是一個(gè)內(nèi)容: URI,該方法將MIME類型
MIMETYPE_TEXT_URILIST 。
使用
newUri()
來從URI,特別是剪輯的內(nèi)容: URI。
-
newIntent(標(biāo)簽,意圖)
-
返回
ClipData 對象,其單
ClipData.Item 對象包含一個(gè)意圖 。該ClipDescription 對象的標(biāo)簽設(shè)置標(biāo)簽 。MIME類型設(shè)置為MIMETYPE_TEXT_INTENT 。
使用
newIntent()
從一個(gè)Intent對象創(chuàng)建一個(gè)剪輯。
強(qiáng)迫剪貼板數(shù)據(jù)為文本
即使您的應(yīng)用程序只能處理文字,您可以通過該方法將其轉(zhuǎn)換從剪貼板復(fù)制非文本數(shù)據(jù)
ClipData.Item.coerceToText() 。
此方法轉(zhuǎn)換數(shù)據(jù)ClipData.Item 文本和返回的CharSequence 。該值
ClipData.Item.coerceToText()
返回基于數(shù)據(jù)的形式ClipData.Item :
- 文本
-
如果
ClipData.Item 是文本(的getText() 不為null),
coerceToText() 返回文本。
- URI
-
如果
ClipData.Item 是一個(gè)URI(getUri() 不為null),
coerceToText() 試圖使用它作為一個(gè)內(nèi)容URI:
- 意圖
-
如果
ClipData.Item 是一個(gè)Intent(getIntent() 不為null),
coerceToText() 將其轉(zhuǎn)換為一個(gè)Intent URI并返回它。的表示是相同的,通過返回
Intent.toUri(URI_INTENT_SCHEME) 。
剪貼板框架總結(jié)于圖1中要復(fù)制的數(shù)據(jù),應(yīng)用程序?qū)⒁粋€(gè)
ClipData 對象上ClipboardManager 全局剪貼板。所述ClipData 包含一個(gè)或多個(gè)
ClipData.Item 對象,一個(gè)
ClipDescription 對象。要粘貼數(shù)據(jù),應(yīng)用程序獲取
ClipData ,從獲取它的MIME類型
ClipDescription ,并且無論是從獲取數(shù)據(jù)ClipData.Item 或由供應(yīng)商所提到的內(nèi)容
ClipData.Item 。
圖1. Android的剪貼板框架
復(fù)制到剪貼板
如前所述,將數(shù)據(jù)復(fù)制到你的句柄全球剪貼板
ClipboardManager 對象,創(chuàng)建一個(gè)ClipData
對象,添加ClipDescription 和一個(gè)或多個(gè)
ClipData.Item 對象給它,并添加完成
ClipData 反對ClipboardManager 對象。這在下面詳細(xì)過程描述:
-
如果您使用的是內(nèi)容URI復(fù)制數(shù)據(jù),建立一個(gè)內(nèi)容提供商。
該
筆記本示例應(yīng)用程序是使用復(fù)制和粘貼內(nèi)容提供商的一個(gè)例子。該
NotePadProvider類實(shí)現(xiàn)內(nèi)容提供商。在
記事本類定義了供應(yīng)商和其他應(yīng)用程序,包括支持的MIME類型之間的契約。
-
獲取系統(tǒng)剪貼板:
...
//如果用戶選擇復(fù)制 的情況下- [R 。ID 。menu_copy :
//獲取一個(gè)句柄到剪貼板服務(wù)。 ClipboardManager 剪貼板= (ClipboardManager ) getSystemService (語境。CLIPBOARD_SERVICE );
-
將數(shù)據(jù)復(fù)制到一個(gè)新的ClipData 對象:
-
對于文本
//創(chuàng)建一個(gè)新的文本剪輯放在剪貼板 ClipData 夾= ClipData 。newPlainText (“純文本” ,“你好,世界!” );
-
對于一個(gè)URI
該片段由編碼記錄ID到內(nèi)容的URI提供商構(gòu)建了一個(gè)URI。這種技術(shù)是覆蓋在一節(jié)更詳細(xì)編碼的URI標(biāo)識符:
//創(chuàng)建一個(gè)基于基本URI,并根據(jù)聯(lián)系人的姓記錄ID上的URI //聲明基本URI字符串 私人 靜態(tài) 最終 字符串聯(lián)系= “內(nèi)容://com.example.contacts” ;
//聲明一個(gè)路徑字符串您使用復(fù)制數(shù)據(jù)URI 私人 靜態(tài) 最終 字符串COPY_PATH = “/復(fù)制” ;
//聲明的URI粘貼到剪貼板 烏里copyUri = 開放的我們。解析(聯(lián)系+ COPY_PATH + “/” + 的lastName );
.. 。
//創(chuàng)建一個(gè)新的URI剪輯對象。該系統(tǒng)采用匿名getContentResolver()對象 //從供應(yīng)商獲得的MIME類型。剪輯對象的標(biāo)簽是“URI”,其數(shù)據(jù)是 //開放的我們以前創(chuàng)建的。 ClipData 夾= ClipData 。newUri (getContentResolver (),“URI” ,copyUri );
-
對于意向
這段代碼構(gòu)建了一個(gè)應(yīng)用程序的意圖,然后把它在剪輯對象:
//創(chuàng)建意圖 意圖appIntent = 新 意圖(此,COM 。例如,演示,所有MyApplication 。類);
...
//創(chuàng)建與它的意圖剪輯對象。它的標(biāo)簽是“意圖”,其數(shù)據(jù)是 //意圖對象先前創(chuàng)建 ClipData 夾= ClipData 。newIntent (“意圖” ,appIntent );
-
將新的剪輯對象剪貼板上:
//設(shè)置剪貼板的主剪輯。 剪貼板。setPrimaryClip (夾);
從剪貼板粘貼
如前所述,您可以通過獲取全局剪貼板對象,得到了剪輯對象,看著它的數(shù)據(jù)從剪貼板粘貼數(shù)據(jù),如果可能從剪輯對象中的數(shù)據(jù)復(fù)制到自己的存儲(chǔ)。本節(jié)詳細(xì)介紹了如何為三種形式剪貼板數(shù)據(jù)的做到這一點(diǎn)。
粘貼純文本
要粘貼純文本,首先獲得全局剪貼板并驗(yàn)證它是否可以返回純文本。然后得到的剪輯對象,并使用其文本復(fù)制到自己的存儲(chǔ)
的getText() ,如以下過程中所述:
-
獲取全球
ClipboardManager 使用對象
getSystemService(CLIPBOARD_SERVICE) 。同時(shí)聲明一個(gè)全局變量包含所粘貼的文本:
ClipboardManager clipboard = ( ClipboardManager ) getSystemService ( Context . CLIPBOARD_SERVICE );
String pasteData = "" ;
-
接下來,確定是否要啟用或禁用當(dāng)前??活動(dòng)的“粘貼”選項(xiàng)。您應(yīng)該驗(yàn)證剪貼板中包含一個(gè)剪輯,并可以處理由剪輯表示的數(shù)據(jù)的類型:
//獲取“粘貼”菜單項(xiàng)的ID 菜單項(xiàng)mPasteItem = 菜單。則findItem (? 。ID 。menu_paste );
//如果剪貼板中不包含數(shù)據(jù),禁用粘貼菜單項(xiàng)。 //如果它不包含數(shù)據(jù),決定是否可以處理
這將禁用粘貼菜單項(xiàng),從剪貼板中有數(shù)據(jù),但它不是純文本 mPasteItem 。的setEnabled (??假); } 其他 {
//這使得粘貼菜單項(xiàng),因?yàn)榧糍N板中包含明文 mPasteItem 。的setEnabled (??真) ; } }
-
將數(shù)據(jù)從復(fù)制到剪貼板。如果“粘貼”菜單項(xiàng)啟用這一點(diǎn)在方案只到達(dá),這樣你就可以假定剪貼板包含純文本。你還不知道它是否包含一個(gè)文本字符串或指向純文本的URI。下面的代碼片段測試,但它只是顯示了處理純文本格式的代碼:
//響應(yīng)用戶選擇“粘貼” 的情況下- [R 。ID 。menu_paste :
//檢查剪貼板上的項(xiàng)目。如果的getText()沒有返回null,剪輯的項(xiàng)目包含 //文本。假定該應(yīng)用程序只能同時(shí)處理一個(gè)項(xiàng)目。 ClipData 。項(xiàng)項(xiàng)= 剪貼板。getPrimaryClip ()。話getItemAt (0 );
//獲取剪貼板為文本。 pasteData = 項(xiàng)目。的getText ();
//如果字符串包含數(shù)據(jù),然后粘貼操作完成后 ,如果 (pasteData != 空) { 返回;
//剪貼板中不包含文本。如果它包含一個(gè)URI,試圖從中獲取數(shù)據(jù) } 其他 { 烏里pasteUri = 項(xiàng)目。getUri ();
//如果URI包含的東西,嘗試從它那里得到的文本 ,如果 (pasteUri != 空) {
//調(diào)用程序來解析URI,并從中獲取數(shù)據(jù)。這個(gè)程序是不是 //這里提出。 pasteData = resolveUri (烏里); 回報(bào); } 其他 {
//東西是錯(cuò)誤的。MIME類型是純文本,但剪貼板中不包含任何 //文本或一個(gè)URI。報(bào)告錯(cuò)誤。 日志。? (“剪貼板中包含一個(gè)無效的數(shù)據(jù)類型” ); 回報(bào); } }
從內(nèi)容URI粘貼數(shù)據(jù)
如果ClipData.Item 對象包含內(nèi)容的URI,你已經(jīng)確定你可以處理它的MIME類型之一,創(chuàng)建一個(gè)
ContentResolver的 ,然后調(diào)用相應(yīng)的內(nèi)容提供商的方法來檢索數(shù)據(jù)。
以下過程介紹如何從內(nèi)容提供商基于在剪貼板上的內(nèi)容URI獲取數(shù)據(jù)。它檢查應(yīng)用程序可以使用MIME類型可以從供應(yīng)商:
-
聲明一個(gè)全局變量包含MIME類型:
//聲明一個(gè)MIME類型常量來匹配由供應(yīng)商提供的MIME類型 的公共 靜態(tài) 最終 字符串MIME_TYPE_CONTACT = “vnd.android.cursor.item / vnd.example.contact”
-
獲得全局剪貼板。還可以獲得內(nèi)容解析,以便您可以訪問內(nèi)容提供商:
//獲取句柄到剪貼板經(jīng)理 ClipboardManager 剪貼板= (ClipboardManager )getSystemService (語境。CLIPBOARD_SERVICE );
//獲取內(nèi)容解析器實(shí)例 ContentResolver的CR = getContentResolver ();
-
獲取剪貼板中的主要片段,并獲得其內(nèi)容為URI:
//獲取剪貼板中的剪貼板數(shù)據(jù) ClipData 夾= 剪貼板。getPrimaryClip ();
如果 (夾!= 空) {
//獲取數(shù)據(jù)從剪貼板中的第一項(xiàng) ClipData 。項(xiàng)項(xiàng)= 夾。話getItemAt (0 );
//嘗試獲取項(xiàng)目的內(nèi)容為URI 烏里pasteUri = 項(xiàng)目。getUri ();
-
測試以查看該URI是一個(gè)內(nèi)容URI通過調(diào)用
的getType(URI) 。如果此方法返回null 烏里 沒有指向一個(gè)有效的內(nèi)容提供商:
//如果剪貼板中包含一個(gè)URI引用 如果 (pasteUri != 空) {
//這是一個(gè)內(nèi)容URI? 字符串uriMimeType = CR 。的getType (pasteUri );
-
測試以查看的內(nèi)容提供商支持的MIME類型,目前的應(yīng)用可以理解的。如果是這樣,調(diào)用
ContentResolver.query() 來獲取數(shù)據(jù)。返回值是一個(gè)
游標(biāo) :
//如果返回值不為空,URI是一個(gè)開放的內(nèi)容 ,如果 (uriMimeType != 空) {
//是否內(nèi)容提供商提供一個(gè)MIME類型,目前的應(yīng)用程序可以使用? 如果 (uriMimeType 。的equals (MIME_TYPE_CONTACT )) {
//從內(nèi)容提供商獲取的數(shù)據(jù)。 光標(biāo)pasteCursor = CR 。查詢(URI , 空, 空, 空, 空);
//如果游標(biāo)包含數(shù)據(jù),移動(dòng)到第一條記錄 ,如果 (pasteCursor != 空) { 如果 (pasteCursor 。moveToFirst ()) {
//從這里光標(biāo)獲取數(shù)據(jù)。代碼將根據(jù)該變化 的數(shù)據(jù)模型的//格式。 } }
//關(guān)閉光標(biāo) pasteCursor 。關(guān)閉(); } } } }
粘貼一個(gè)Intent
要粘貼一個(gè)Intent,首先獲得全局剪貼板。檢查
ClipData.Item 對象以查看它是否包含一個(gè)意圖。然后調(diào)用
getIntent() 的意圖復(fù)制到自己的存儲(chǔ)。下面的代碼演示這一點(diǎn):
//獲取句柄到剪貼板經(jīng)理 ClipboardManager 剪貼板= (ClipboardManager )getSystemService (語境。CLIPBOARD_SERVICE );
//檢查是否剪輯項(xiàng)目包含一個(gè)Intent,通過測試,看是否getIntent()返回null 意向pasteIntent = 剪貼板。getPrimaryClip ()話getItemAt (0 )。getIntent ();
如果 (pasteIntent != 空) {
//處理這個(gè)意圖
} 其他 {
//忽略剪貼板,或發(fā)出一個(gè)錯(cuò)誤,如果你的應(yīng)用程序所期待的意圖是 //剪貼板上 }
使用內(nèi)容提供商能夠復(fù)制復(fù)雜數(shù)據(jù)
內(nèi)容提供商支持復(fù)制,如數(shù)據(jù)庫記錄或文件流復(fù)雜的數(shù)據(jù)。要復(fù)制的數(shù)據(jù),你把剪貼板內(nèi)容URI。粘貼應(yīng)用程序然后從剪貼板中得到這個(gè)URI,并用它來檢索數(shù)據(jù)庫中的數(shù)據(jù)或文件流描述符。
由于粘貼應(yīng)用程序只有為你的數(shù)據(jù)內(nèi)容的URI,它需要知道要檢索的數(shù)據(jù)塊。您可以通過在URI本身編碼為數(shù)據(jù)的標(biāo)識符提供該信息,或者您也可以提供一個(gè)獨(dú)特的URI,將返回要復(fù)制的數(shù)據(jù)。哪種技術(shù)選擇取決于數(shù)據(jù)的組織。
以下各節(jié)描述了如何設(shè)置的URI,如何提供復(fù)雜的數(shù)據(jù),以及如何提供文件流。該描述假定您熟悉內(nèi)容提供商設(shè)計(jì)的一般原則。
編碼的URI的標(biāo)識符
為將數(shù)據(jù)復(fù)制到一個(gè)URI剪貼板一個(gè)有用的方法是進(jìn)行編碼的標(biāo)識符的URI本身的數(shù)據(jù)。然后內(nèi)容提供商可以從URI中的標(biāo)識符,并使用它來檢索數(shù)據(jù)。粘貼應(yīng)用程序不必知道該標(biāo)識符的存在; 所有它做的是從剪貼板讓你“參考”(URI中加上標(biāo)識符),給它的內(nèi)容提供商,并取回?cái)?shù)據(jù)。
你通常通過它串聯(lián)到URI的末尾標(biāo)識符編碼到URI的內(nèi)容。例如,假設(shè)你定義你的供應(yīng)商URI作為下面的字符串:
“內(nèi)容://com.example.contacts”
如果你想要的名稱編碼到這個(gè)URI,你可以使用下面的代碼片段:
字符串uriString中= “內(nèi)容://com.example.contacts” + “/” + “史密斯”
// uriString中現(xiàn)在包含的內(nèi)容://com.example.contacts/Smith。
//從字符串表示生成一個(gè)URI對象 的Uri copyUri = 開放的我們。解析(uriString中);
如果您已經(jīng)使用內(nèi)容提供商,您可能要添加,表示URI是復(fù)制一個(gè)新的URI路徑。例如,假設(shè)你已經(jīng)擁有以下URI路徑:
"content://com.example.contacts" / people "content://com.example.contacts" / people / detail "content://com.example.contacts" / people / images
你可以添加另一個(gè)路徑是特定于復(fù)制的URI:
“內(nèi)容://com.example.contacts/copying”
然后,您可以通過模式匹配檢測“復(fù)制”URI和代碼,具體的復(fù)制和粘貼處理。
你通常如果你已經(jīng)在使用一個(gè)內(nèi)容提供商,內(nèi)部數(shù)據(jù)庫,或內(nèi)部表來組織你的數(shù)據(jù)使用的編碼技術(shù)。在這些情況下,您有多個(gè)作品,你要復(fù)制的數(shù)據(jù),大概每件的唯一標(biāo)識符。在回答粘貼申請查詢時(shí),您可以通過其標(biāo)識符查找數(shù)據(jù)并將其返回。
如果沒有多個(gè)數(shù)據(jù),那么你可能不需要進(jìn)行編碼的標(biāo)識符。你可以簡單地使用URI所獨(dú)有的提供商。在回應(yīng)查詢時(shí),您的供應(yīng)商將返回它目前包含的數(shù)據(jù)。
過得去ID一個(gè)記錄在使用
筆記本的示例應(yīng)用程序從筆記列表中打開一張紙條。該示例使用_id 字段從一個(gè)SQL數(shù)據(jù)庫,但你可以有你想要的任何數(shù)字或字符的標(biāo)識符。
復(fù)制數(shù)據(jù)結(jié)構(gòu)
您設(shè)置復(fù)制和粘貼復(fù)雜的數(shù)據(jù)內(nèi)容提供商作為的一個(gè)子類
ContentProvider的 組成部分。你也應(yīng)該編碼URI你把剪貼板,使其指向要提供確切的記錄。另外,你必須考慮你的應(yīng)用程序的現(xiàn)有狀態(tài):
-
如果你已經(jīng)有了一個(gè)內(nèi)容提供商,您可以添加到它的功能。您可能只需要修改其
查詢()
方法來處理的URI從要粘貼數(shù)據(jù)的應(yīng)用程序來。你可能會(huì)想修改來處理“復(fù)制”URI模式的方法。
-
如果你的應(yīng)用程序維護(hù)一個(gè)內(nèi)部數(shù)據(jù)庫,您可能希望該數(shù)據(jù)庫移動(dòng)到內(nèi)容提供商,以便從它拷貝。
-
如果你目前沒有使用數(shù)據(jù)庫,可以實(shí)現(xiàn)一個(gè)簡單的內(nèi)容提供商,其唯一目的是提供數(shù)據(jù)的應(yīng)用程序,從剪貼板粘貼。
在內(nèi)容提供商,你將要覆蓋至少有以下方法:
-
查詢()
-
粘貼的應(yīng)用程序會(huì)認(rèn)為他們可以通過使用此方法,你把剪貼板上的URI獲取數(shù)據(jù)。為了支持復(fù)制,你應(yīng)該有這種方法檢測含有一種特殊的“復(fù)制”路徑的URI。然后,應(yīng)用程序可以創(chuàng)建一個(gè)“復(fù)制”URI放在剪貼板上,包含副本路徑和一個(gè)指向要復(fù)制的準(zhǔn)確記錄。
-
的getType()
-
這個(gè)方法應(yīng)該返回的MIME類型或類型為你打算復(fù)制數(shù)據(jù)。該方法
newUri() 調(diào)用
的getType() ,以將MIME類型到新ClipData 對象。
MIME類型復(fù)雜數(shù)據(jù)中的主題描述
內(nèi)容提供商。
注意,不必有任何的其他內(nèi)容提供者的方法,如
插入件() 或
更新() 。一個(gè)粘貼應(yīng)用程序只需要得到您的支持的MIME類型,并從供應(yīng)商復(fù)制數(shù)據(jù)。如果你已經(jīng)有了這些方法,他們不會(huì)復(fù)制操作干擾。
下面的代碼片段demonsrate如何設(shè)置你的應(yīng)用程序來復(fù)制復(fù)雜的數(shù)據(jù):
-
在您的應(yīng)用程序的全局常量,聲明基本URI字符串,標(biāo)識您正在使用復(fù)制數(shù)據(jù)的URI字符串的路徑。同時(shí)聲明MIME類型為復(fù)制的數(shù)據(jù):
//聲明基本URI字符串 私人 靜態(tài) 最終 字符串聯(lián)系= “內(nèi)容://com.example.contacts” ;
//聲明為您用來復(fù)制數(shù)據(jù)URI路徑字符串 私人 靜態(tài) 最終 字符串COPY_PATH = “/復(fù)制” ;
//聲明一個(gè)MIME類型復(fù)制的數(shù)據(jù) 公共 靜態(tài) 最終 字符串MIME_TYPE_CONTACT = “vnd.android.cursor.item / vnd.example.contact”
-
在從用戶拷貝數(shù)據(jù)的活動(dòng),設(shè)置代碼將數(shù)據(jù)復(fù)制到剪貼板。在回答一個(gè)副本的請求,把URI剪貼板上:
公共 類 MyCopyActivity 擴(kuò)展 活動(dòng) {
...
//用戶已經(jīng)選擇了名稱,并請求副本。 案例- [R ,ID 。menu_copy :
//追加姓氏基礎(chǔ)URI //名稱存儲(chǔ)在“姓氏” uriString中= 聯(lián)系+ COPY_PATH + “/” + 的lastName ;
//將字符串成一個(gè)URI 烏里copyUri = 開放的我們。解析(uriString中);
//獲取句柄到剪貼板
將剪貼板中的主剪輯。 剪貼板。setPrimaryClip (夾);
-
在內(nèi)容提供商在全球范圍內(nèi),建立一個(gè)URI匹配,并添加一個(gè)URI模式將匹配你把剪貼板上的URI:
公共 類 MyCopyProvider 擴(kuò)展 ContentProvider的 {
...
//一個(gè)開放的匹配對象,它簡化了內(nèi)容的URI匹配模式。 私人 靜態(tài) 最終 UriMatcher sURIMatcher = 新 UriMatcher (UriMatcher 。NO_MATCH );
//一個(gè)整數(shù),開關(guān)會(huì)根據(jù)輸入的URI使用圖案 私人 靜態(tài) 最終 INT GET_SINGLE_CONTACT = 0 ;
...
//增加了對內(nèi)容的URI的匹配。它匹配 //“的內(nèi)容://com.example.contacts/copy/*” sUriMatcher 。addURI (聯(lián)系, “名/ *” ,GET_SINGLE_CONTACT );
-
建立
查詢()
方法。這種方法可以處理不同的URI模式,這取決于你如何編寫代碼,但只顯示為剪貼板復(fù)制操作模式:
//設(shè)置你的供應(yīng)商的查詢()
根據(jù)輸入的內(nèi)容URI在Switch 開關(guān) (sUriMatcher 。比賽(URI )) {
案件GET_SINGLE_CONTACT :
//查詢并返回被請求的名字聯(lián)系。在這里,您將解碼 //傳入的URI,查詢基礎(chǔ)上,姓氏的數(shù)據(jù)模型,并返回結(jié)果 //作為光標(biāo)。
...
}
-
設(shè)立的getType() 方法返回一個(gè)適當(dāng)?shù)腗IME類型復(fù)制的數(shù)據(jù):
//設(shè)置您的提供商的getType() method. public String getType ( Uri uri ) {
...
switch ( sUriMatcher . match ( uri )) {
case GET_SINGLE_CONTACT :
return ( MIME_TYPE_CONTACT );
本節(jié)從內(nèi)容粘貼數(shù)據(jù)URI
介紹了如何從剪貼板中獲取內(nèi)容URI,并使用它來 ??獲取和粘貼數(shù)據(jù)。
復(fù)制數(shù)據(jù)流
您可以復(fù)制并粘貼大量的文本和二進(jìn)制數(shù)據(jù)流。該數(shù)據(jù)可以具有形式如下列:
-
存儲(chǔ)在實(shí)際設(shè)備上的文件。
-
從插座流。
-
大量存儲(chǔ)在提供商的基礎(chǔ)數(shù)據(jù)庫系統(tǒng)中的數(shù)據(jù)。
數(shù)據(jù)流的內(nèi)容提供商提供了一個(gè)文件描述符對象訪問其數(shù)據(jù),如AssetFileDescriptor 而不是
光標(biāo) 對象。粘貼應(yīng)用程序讀取使用該文件描述符中的數(shù)據(jù)流。
要設(shè)置您的應(yīng)用程序與供應(yīng)商復(fù)制數(shù)據(jù)流,請按照下列步驟操作:
-
數(shù)據(jù)流你把剪貼板上設(shè)置了內(nèi)容URI。這樣做的選擇包括以下內(nèi)容:
-
編碼數(shù)據(jù)流的識別符上的URI,如在部分中所述
編碼對URI的標(biāo)識符,然后保持在提供商包含標(biāo)識符和相應(yīng)的流名稱的表。
-
直接在URI編碼流的名稱。
-
使用唯一的URI總是返回從提供當(dāng)前流。如果你使用這個(gè)選項(xiàng),你要記得更新你的供應(yīng)商,指向不同的流時(shí),你流復(fù)制到通過URI剪貼板。
-
提供一個(gè)MIME類型為您計(jì)劃提供每種類型的數(shù)據(jù)流。粘貼應(yīng)用程序需要這些信息來確定是否可以粘貼剪貼板上的數(shù)據(jù)。
-
實(shí)施中的一個(gè)
的ContentProvider 返回文件描述符要流的方法。如果你的內(nèi)容URI標(biāo)識編碼,使用這種方法來確定要打開的流。
-
到數(shù)據(jù)流復(fù)制到剪貼板,建設(shè)內(nèi)容URI并將其放在剪貼板上。
要粘貼數(shù)據(jù)流,一個(gè)應(yīng)用程序獲取的剪輯從剪貼板,獲取URI,并使用它在一個(gè)呼叫ContentResolver的 打開的流文件描述方法。該ContentResolver的 方法調(diào)用相應(yīng)的
ContentProvider的 方法,傳遞內(nèi)容的URI。你的供應(yīng)商返回的文件描述符ContentResolver的 方法。粘貼然后應(yīng)用程序有責(zé)任從流中讀取數(shù)據(jù)。
下面的列表顯示了內(nèi)容提供商最重要的文件描述符的方法。每一個(gè)都有一個(gè)相應(yīng)ContentResolver的 方法與字符串“描述符”追加到方法名稱; 例如,
ContentResolver的 模擬
openAssetFile() 是
openAssetFileDescriptor() :
-
openTypedAssetFile()
-
此方法應(yīng)返回一個(gè)資產(chǎn)的文件描述符,但只有當(dāng)提供MIME類型由提供者的支持。主叫方(應(yīng)用程序做粘貼)提供了一個(gè)MIME類型模式。(已復(fù)制了URI到剪貼板的應(yīng)用程序)的內(nèi)容提供商返回
AssetFileDescriptor 文件句柄,如果它可以提供MIME類型,或者拋出,如果它不能例外。
此方法處理文件的小節(jié)。你可以用它來閱讀內(nèi)容提供商已經(jīng)復(fù)制到剪貼板資產(chǎn)。
-
openAssetFile()
-
這種方法是一種更一般的形式
openTypedAssetFile() 。它不會(huì)過濾允許的MIME類型,但它可以讀取文件的小節(jié)。
-
打開文件()
-
這是一個(gè)更一般的形式
openAssetFile() 。它不能讀取文件的小節(jié)。
您可以選擇使用
openPipeHelper()
方法與你的文件描述符的方法。這使得應(yīng)用程序粘貼在使用管道后臺線程讀取數(shù)據(jù)流。要使用此方法,您需要實(shí)現(xiàn)
ContentProvider.PipeDataWriter 接口。這樣的例子在給出筆記本示例應(yīng)用程序,在openTypedAssetFile() 的方法
NotePadProvider.java 。
設(shè)計(jì)有效的復(fù)制/粘貼功能
要設(shè)計(jì)有效的復(fù)制和粘貼功能為您的應(yīng)用程序,請記住以下幾點(diǎn):
-
在任何時(shí)候,只有一個(gè)在剪貼板剪輯。通過系統(tǒng)中的任何應(yīng)用程序的新副本操作將覆蓋以前的剪輯。由于用戶可以導(dǎo)航到你的應(yīng)用程序,距離返回前做一個(gè)副本,你不能假設(shè)剪貼板中包含了用戶在先前復(fù)制剪輯您的
應(yīng)用程序。
-
多的預(yù)期目的
ClipData.Item
每剪輯對象是支持多個(gè)選擇的復(fù)制和粘貼,而不是不同的形式的參考單個(gè)選擇。您通常希望所有的
ClipData.Item 短片中的對象具有相同的形式,即,他們都應(yīng)該是簡單的文本,內(nèi)容URI或意向 ,但不是的混合物。
-
當(dāng)您提供的數(shù)據(jù),可以提供不同的MIME表示。添加您的支持MIME類型
ClipDescription ,然后實(shí)現(xiàn)在內(nèi)容提供商的MIME類型。
-
當(dāng)您從剪貼板中獲取數(shù)據(jù),您的應(yīng)用程序負(fù)責(zé)檢查可用的MIME類型,然后決定使用哪一個(gè),如果有的話。即使是在剪貼板上的夾子和用戶請求糊狀,您的應(yīng)用程序不需要進(jìn)行粘貼。你應(yīng)該做的,如果貼的MIME類型是兼容的。您可以選擇強(qiáng)迫剪貼板上的數(shù)據(jù)使用文本
coerceToText() ,如果你選擇。如果你的應(yīng)用程序支持的可用MIME類型不止一個(gè),你可以允許用戶選擇使用哪一個(gè)。
|