Android提供复制和粘贴功能强大的基于剪贴板的框架。它支持简单和复杂的数据类型,包括文本串,复杂的数据结构,文本和二进制数据流,甚至应用的资产。简单的文本数据被直接存储在剪贴板中,而复杂的数据被存储作为该粘贴应用程序与内容提供商解析的引用。复制和粘贴都在应用程序中,并实现了框架的应用程序之间进行。
由于框架的一部分使用内容提供商,这个主题假定一些熟悉Android的内容提供商的API,这是在主题中介绍
的内容提供商。
剪贴板框架
当您使用剪贴板框架,你把数据转化为剪辑对象,然后把剪辑对象在全系统剪贴板。剪辑对象可以采取三种形式:
文本
文本字符串。您可以直接把串入剪辑对象,您然后将复制到剪贴板。要粘贴字符串,将剪贴板中的剪辑对象和字符串复制到您的应用程序的存储。
URI
一个
意图
一个
剪贴板只拥有一次剪辑对象。当应用程序将一个剪辑对象在剪贴板上,以前的剪辑对象消失。
如果你希望允许用户将数据粘贴到你的应用程序,你不必处理所有类型的数据。给你的用户将其粘贴选项之前,您可以检查剪贴板上的数据。除了具有一定的数据格式,剪辑对象也包含了告诉你什么MIME类型或类型可用的元数据。该元数据可以帮助你决定??是否你的应用程序可以做一些与剪贴板数据非常有用。例如,如果你有一个应用程序,主要处理可能要忽略包含URI或意图剪辑对象的文本。
您也可以允许用户将文本粘贴无论在剪贴板上的数据的形式。要做到这一点,您可以强制剪贴板数据转换成文本表示,然后粘贴这个文本。这是一节中所述强制转换剪贴板文本。
剪贴板类
本节介绍剪贴板框架使用的类。
ClipboardManager
在Android系统中,系统剪贴板是由全球代表
ClipData,ClipData.Item和ClipDesc??ription
将数据添加到剪贴板中,您可以创建一个
一个
一个
文本
URI
一个
意图
一个
您可以添加多个
ClipData方便的方法
强迫剪贴板数据为文本
即使您的应用程序只能处理文字,您可以通过该方法将其转换从剪贴板复制非文本数据
文本
URI
如果如果URI是一个内容URI和提供者可以返回文本流,
如果URI是一个内容URI,但供应商不提供一个文本流,
如果URI是不是内容的URI,
意图
图1. Android的剪贴板框架
复制到剪贴板
如果您使用的是内容URI复制数据,建立一个内容提供商。
该笔记本示例应用程序是使用复制和粘贴内容提供商的一个例子。该
NotePadProvider类实现内容提供商。在
记事本类定义了供应商和其他应用程序,包括支持的MIME类型之间的契约。
获取系统剪贴板:
...
//如果用户选择复制
的情况下- [R 。ID 。menu_copy :
//获取一个句柄到剪贴板服务。
ClipboardManager 剪贴板= (ClipboardManager )
getSystemService (语境。CLIPBOARD_SERVICE );
将数据复制到一个新的
对于文本
//创建一个新的文本剪辑放在剪贴板
ClipData 夹= ClipData 。newPlainText (“纯文本” ,“你好,世界!” );
对于一个URI
该片段由编码记录ID到内容的URI提供商构建了一个URI。这种技术是覆盖在一节更详细编码的URI标识符:
//创建一个基于基本URI,并根据联系人的姓记录ID上的URI
//声明基本URI字符串
私人 静态 最终 字符串联系= “内容://com.example.contacts” ;
//声明一个路径字符串您使用复制数据URI
私人 静态 最终 字符串COPY_PATH = “/复制” ;
//声明的URI粘贴到剪贴板
乌里copyUri = 开放的我们。解析(联系+ COPY_PATH + “/” + 的lastName );
.. 。
//创建一个新的URI剪辑对象。该系统采用匿名getContentResolver()对象
//从供应商获得的MIME类型。剪辑对象的标签是“URI”,其数据是
//开放的我们以前创建的。
ClipData 夹= ClipData 。newUri (getContentResolver (),“URI” ,copyUri );
对于意向
这段代码构建了一个应用程序的意图,然后把它在剪辑对象:
//创建意图
意图appIntent = 新 意图(此,COM 。例如,演示,所有MyApplication 。类);
...
//创建与它的意图剪辑对象。它的标签是“意图”,其数据是
//意图对象先前创建
ClipData 夹= ClipData 。newIntent (“意图” ,appIntent );
将新的剪辑对象剪贴板上:
//设置剪贴板的主剪辑。
剪贴板。setPrimaryClip (夹);
从剪贴板粘贴
如前所述,您可以通过获取全局剪贴板对象,得到了剪辑对象,看着它的数据从剪贴板粘贴数据,如果可能从剪辑对象中的数据复制到自己的存储。本节详细介绍了如何为三种形式剪贴板数据的做到这一点。
粘贴纯文本
要粘贴纯文本,首先获得全局剪贴板并验证它是否可以返回纯文本。然后得到的剪辑对象,并使用其文本复制到自己的存储
获取全球ClipboardManager clipboard = ( ClipboardManager ) getSystemService ( Context . CLIPBOARD_SERVICE );
String pasteData = "" ;
接下来,确定是否要启用或禁用当前??活动的“粘贴”选项。您应该验证剪贴板中包含一个剪辑,并可以处理由剪辑表示的数据的类型:
//获取“粘贴”菜单项的ID
菜单项mPasteItem = 菜单。则findItem (? 。ID 。menu_paste );
//如果剪贴板中不包含数据,禁用粘贴菜单项。
//如果它不包含数据,决定是否可以处理
这将禁用粘贴菜单项,从剪贴板中有数据,但它不是纯文本
mPasteItem 。的setEnabled (??假);
} 其他 {
//这使得粘贴菜单项,因为剪贴板中包含明文
mPasteItem 。的setEnabled (??真) ;
}
}
将数据从复制到剪贴板。如果“粘贴”菜单项启用这一点在方案只到达,这样你就可以假定剪贴板包含纯文本。你还不知道它是否包含一个文本字符串或指向纯文本的URI。下面的代码片段测试,但它只是显示了处理纯文本格式的代码:
//响应用户选择“粘贴”
的情况下- [R 。ID 。menu_paste :
//检查剪贴板上的项目。如果的getText()没有返回null,剪辑的项目包含
//文本。假定该应用程序只能同时处理一个项目。
ClipData 。项项= 剪贴板。getPrimaryClip ()。话getItemAt (0 );
//获取剪贴板为文本。
pasteData = 项目。的getText ();
//如果字符串包含数据,然后粘贴操作完成后
,如果 (pasteData != 空) {
返回;
//剪贴板中不包含文本。如果它包含一个URI,试图从中获取数据
} 其他 {
乌里pasteUri = 项目。getUri ();
//如果URI包含的东西,尝试从它那里得到的文本
,如果 (pasteUri != 空) {
//调用程序来解析URI,并从中获取数据。这个程序是不是
//这里提出。
pasteData = resolveUri (乌里);
回报;
} 其他 {
//东西是错误的。MIME类型是纯文本,但剪贴板中不包含任何
//文本或一个URI。报告错误。
日志。? (“剪贴板中包含一个无效的数据类型” );
回报;
}
}
从内容URI粘贴数据
如果
以下过程介绍如何从内容提供商基于在剪贴板上的内容URI获取数据。它检查应用程序可以使用MIME类型可以从供应商:
声明一个全局变量包含MIME类型:
//声明一个MIME类型常量来匹配由供应商提供的MIME类型
的公共 静态 最终 字符串MIME_TYPE_CONTACT = “vnd.android.cursor.item / vnd.example.contact”
获得全局剪贴板。还可以获得内容解析,以便您可以访问内容提供商:
//获取句柄到剪贴板经理
ClipboardManager 剪贴板= (ClipboardManager )getSystemService (语境。CLIPBOARD_SERVICE );
//获取内容解析器实例
ContentResolver的CR = getContentResolver ();
获取剪贴板中的主要片段,并获得其内容为URI:
//获取剪贴板中的剪贴板数据
ClipData 夹= 剪贴板。getPrimaryClip ();
如果 (夹!= 空) {
//获取数据从剪贴板中的第一项
ClipData 。项项= 夹。话getItemAt (0 );
//尝试获取项目的内容为URI
乌里pasteUri = 项目。getUri ();
测试以查看该URI是一个内容URI通过调用
乌里没有指向一个有效的内容提供商:
//如果剪贴板中包含一个URI引用
如果 (pasteUri != 空) {
//这是一个内容URI?
字符串uriMimeType = CR 。的getType (pasteUri );
测试以查看的内容提供商支持的MIME类型,目前的应用可以理解的。如果是这样,调用
//如果返回值不为空,URI是一个开放的内容
,如果 (uriMimeType != 空) {
//是否内容提供商提供一个MIME类型,目前的应用程序可以使用?
如果 (uriMimeType 。的equals (MIME_TYPE_CONTACT )) {
//从内容提供商获取的数据。
光标pasteCursor = CR 。查询(URI , 空, 空, 空, 空);
//如果游标包含数据,移动到第一条记录
,如果 (pasteCursor != 空) {
如果 (pasteCursor 。moveToFirst ()) {
//从这里光标获取数据。代码将根据该变化
的数据模型的//格式。
}
}
//关闭光标
pasteCursor 。关闭();
}
}
}
}
粘贴一个Intent
要粘贴一个Intent,首先获得全局剪贴板。检查
//获取句柄到剪贴板经理
ClipboardManager 剪贴板= (ClipboardManager )getSystemService (语境。CLIPBOARD_SERVICE );
//检查是否剪辑项目包含一个Intent,通过测试,看是否getIntent()返回null
意向pasteIntent = 剪贴板。getPrimaryClip ()话getItemAt (0 )。getIntent ();
如果 (pasteIntent != 空) {
//处理这个意图
} 其他 {
//忽略剪贴板,或发出一个错误,如果你的应用程序所期待的意图是
//剪贴板上
}
使用内容提供商能够复制复杂数据
内容提供商支持复制,如数据库记录或文件流复杂的数据。要复制的数据,你把剪贴板内容URI。粘贴应用程序然后从剪贴板中得到这个URI,并用它来检索数据库中的数据或文件流描述符。
由于粘贴应用程序只有为你的数据内容的URI,它需要知道要检索的数据块。您可以通过在URI本身编码为数据的标识符提供该信息,或者您也可以提供一个独特的URI,将返回要复制的数据。哪种技术选择取决于数据的组织。
以下各节描述了如何设置的URI,如何提供复杂的数据,以及如何提供文件流。该描述假定您熟悉内容提供商设计的一般原则。
编码的URI的标识符
为将数据复制到一个URI剪贴板一个有用的方法是进行编码的标识符的URI本身的数据。然后内容提供商可以从URI中的标识符,并使用它来检索数据。粘贴应用程序不必知道该标识符的存在; 所有它做的是从剪贴板让你“参考”(URI中加上标识符),给它的内容提供商,并取回数据。
你通常通过它串联到URI的末尾标识符编码到URI的内容。例如,假设你定义你的供应商URI作为下面的字符串:
“内容://com.example.contacts”
如果你想要的名称编码到这个URI,你可以使用下面的代码片段:
字符串uriString中= “内容://com.example.contacts” + “/” + “史密斯”
// uriString中现在包含的内容://com.example.contacts/Smith。
//从字符串表示生成一个URI对象
的Uri copyUri = 开放的我们。解析(uriString中);
如果您已经使用内容提供商,您可能要添加,表示URI是复制一个新的URI路径。例如,假设你已经拥有以下URI路径:
"content://com.example.contacts" / people
"content://com.example.contacts" / people / detail
"content://com.example.contacts" / people / images
你可以添加另一个路径是特定于复制的URI:
“内容://com.example.contacts/copying”
然后,您可以通过模式匹配检测“复制”URI和代码,具体的复制和粘贴处理。
你通常如果你已经在使用一个内容提供商,内部数据库,或内部表来组织你的数据使用的编码技术。在这些情况下,您有多个作品,你要复制的数据,大概每件的唯一标识符。在回答粘贴申请查询时,您可以通过其标识符查找数据并将其返回。
如果没有多个数据,那么你可能不需要进行编码的标识符。你可以简单地使用URI所独有的提供商。在回应查询时,您的供应商将返回它目前包含的数据。
过得去ID一个记录在使用
笔记本的示例应用程序从笔记列表中打开一张纸条。该示例使用_id字段从一个SQL数据库,但你可以有你想要的任何数字或字符的标识符。
复制数据结构
您设置复制和粘贴复杂的数据内容提供商作为的一个子类
如果你已经有了一个内容提供商,您可以添加到它的功能。您可能只需要修改其
如果你的应用程序维护一个内部数据库,您可能希望该数据库移动到内容提供商,以便从它拷贝。
如果你目前没有使用数据库,可以实现一个简单的内容提供商,其唯一目的是提供数据的应用程序,从剪贴板粘贴。
在内容提供商,你将要覆盖至少有以下方法:
粘贴的应用程序会认为他们可以通过使用此方法,你把剪贴板上的URI获取数据。为了支持复制,你应该有这种方法检测含有一种特殊的“复制”路径的URI。然后,应用程序可以创建一个“复制”URI放在剪贴板上,包含副本路径和一个指向要复制的准确记录。
这个方法应该返回的MIME类型或类型为你打算复制数据。该方法
MIME类型复杂数据中的主题描述
内容提供商。
注意,不必有任何的其他内容提供者的方法,如
下面的代码片段demonsrate如何设置你的应用程序来复制复杂的数据:
在您的应用程序的全局常量,声明基本URI字符串,标识您正在使用复制数据的URI字符串的路径。同时声明MIME类型为复制的数据:
//声明基本URI字符串
私人 静态 最终 字符串联系= “内容://com.example.contacts” ;
//声明为您用来复制数据URI路径字符串
私人 静态 最终 字符串COPY_PATH = “/复制” ;
//声明一个MIME类型复制的数据
公共 静态 最终 字符串MIME_TYPE_CONTACT = “vnd.android.cursor.item / vnd.example.contact”
在从用户拷贝数据的活动,设置代码将数据复制到剪贴板。在回答一个副本的请求,把URI剪贴板上:
公共 类 MyCopyActivity 扩展 活动 {
...
//用户已经选择了名称,并请求副本。
案例- [R ,ID 。menu_copy :
//追加姓氏基础URI
//名称存储在“姓氏”
uriString中= 联系+ COPY_PATH + “/” + 的lastName ;
//将字符串成一个URI
乌里copyUri = 开放的我们。解析(uriString中);
//获取句柄到剪贴板
将剪贴板中的主剪辑。
剪贴板。setPrimaryClip (夹);
在内容提供商在全球范围内,建立一个URI匹配,并添加一个URI模式将匹配你把剪贴板上的URI:
公共 类 MyCopyProvider 扩展 ContentProvider的 {
...
//一个开放的匹配对象,它简化了内容的URI匹配模式。
私人 静态 最终 UriMatcher sURIMatcher = 新 UriMatcher (UriMatcher 。NO_MATCH );
//一个整数,开关会根据输入的URI使用图案
私人 静态 最终 INT GET_SINGLE_CONTACT = 0 ;
...
//增加了对内容的URI的匹配。它匹配
//“的内容://com.example.contacts/copy/*”
sUriMatcher 。addURI (联系, “名/ *” ,GET_SINGLE_CONTACT );
建立
//设置你的供应商的查询()
根据输入的内容URI在Switch
开关 (sUriMatcher 。比赛(URI )) {
案件GET_SINGLE_CONTACT :
//查询并返回被请求的名字联系。在这里,您将解码
//传入的URI,查询基础上,姓氏的数据模型,并返回结果
//作为光标。
...
}
设立
//设置您的提供商的getType() method.
public String getType ( Uri uri ) {
...
switch ( sUriMatcher . match ( uri )) {
case GET_SINGLE_CONTACT :
return ( MIME_TYPE_CONTACT );
本节从内容粘贴数据URI
介绍了如何从剪贴板中获取内容URI,并使用它来 ??获取和粘贴数据。
复制数据流
您可以复制并粘贴大量的文本和二进制数据流。该数据可以具有形式如下列:
存储在实际设备上的文件。
从插座流。
大量存储在提供商的基础数据库系统中的数据。
数据流的内容提供商提供了一个文件描述符对象访问其数据,如
要设置您的应用程序与供应商复制数据流,请按照下列步骤操作:
数据流你把剪贴板上设置了内容URI。这样做的选择包括以下内容:
编码数据流的识别符上的URI,如在部分中所述
编码对URI的标识符,然后保持在提供商包含标识符和相应的流名称的表。
直接在URI编码流的名称。
使用唯一的URI总是返回从提供当前流。如果你使用这个选项,你要记得更新你的供应商,指向不同的流时,你流复制到通过URI剪贴板。
提供一个MIME类型为您计划提供每种类型的数据流。粘贴应用程序需要这些信息来确定是否可以粘贴剪贴板上的数据。
实施中的一个
到数据流复制到剪贴板,建设内容URI并将其放在剪贴板上。
要粘贴数据流,一个应用程序获取的剪辑从剪贴板,获取URI,并使用它在一个呼叫
此方法应返回一个资产的文件描述符,但只有当提供MIME类型由提供者的支持。主叫方(应用程序做粘贴)提供了一个MIME类型模式。(已复制了URI到剪贴板的应用程序)的内容提供商返回
此方法处理文件的小节。你可以用它来阅读内容提供商已经复制到剪贴板资产。
这种方法是一种更一般的形式
这是一个更一般的形式
您可以选择使用
笔记本示例应用程序,在openTypedAssetFile()的方法
NotePadProvider.java。
设计有效的复制/粘贴功能
要设计有效的复制和粘贴功能为您的应用程序,请记住以下几点:
在任何时候,只有一个在剪贴板剪辑。通过系统中的任何应用程序的新副本操作将覆盖以前的剪辑。由于用户可以导航到你的应用程序,距离返回前做一个副本,你不能假设剪贴板中包含了用户在先前复制剪辑您的
应用程序。
多的预期目的
当您提供的数据,可以提供不同的MIME表示。添加您的支持MIME类型
当您从剪贴板中获取数据,您的应用程序负责检查可用的MIME类型,然后决定使用哪一个,如果有的话。即使是在剪贴板上的夹子和用户请求糊状,您的应用程序不需要进行粘贴。你应该做的,如果贴的MIME类型是兼容的。您可以选择强迫剪贴板上的数据使用文本