把数据复制到剪贴板
如前所述,要把数据复制到剪贴板,你需要获取一个全局的ClipboardManager对象,用它再创建一个ClipData对象,然后把一个ClipDescription和一个或多个ClipData.Item对象添加到ClipData对象中,最后把ClipData对象添加回ClipboardManager对象中,详细过程如下:
1. 如果使用内容URI来复制数据,那么就要建立一个内容提供器。
Note Pad示例应用程序使用内容提供器来复制和粘贴数据。NotePadProvider类实现该内容提供器。NotePad类定义提供器和其他应用程序之间的约定,包括支持的MIME类型。
2. 获得系统剪贴板:
...
// if the user selects copy
case R.id.menu_copy:
// Gets a handle to the clipboard service.
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
3. 把数据复制到一个新的ClipData对象中:
A. 文本数据:
// Creates a new text clip to put on the clipboard
ClipData clip =ClipData.newPlainText("simple text","Hello, World!");
B. URI数据
以下代码把一个记录ID编码到对应的提供器的内容URI上。这项技术会在URI标识编码中详细介绍。
// Creates a Uri based on a base Uri and a record ID based on the contact's last name
// Declares the base URI string
privatestaticfinalString CONTACTS ="content://com.example.contacts";
// Declares a path string for URIs that you use to copy data
privatestaticfinalString COPY_PATH ="/copy";
// Declares the Uri to paste to the clipboard
Uri copyUri =Uri.parse(CONTACTS + COPY_PATH +"/"+ lastName);
...
// Creates a new URI clip object. The system uses the anonymous getContentResolver() object to
// get MIME types from provider. The clip object's label is "URI", and its data is
// the Uri previously created.
ClipData clip =ClipData.newUri(getContentResolver(),"URI",copyUri);
C. Intent数据
以下代码构造了一个对应应用程序的Intent对象,然后把它放到剪贴对象中:
// Creates the Intent
Intent appIntent = new Intent(this, com.example.demo.myapplication.class);
...
// Creates a clip object with the Intent in it. Its label is "Intent" and its data is
// the Intent object created previously
ClipData clip = ClipData.newIntent("Intent",appIntent);
4. 把新的剪贴对象放到剪贴板上:
// Set the clipboard's primary clip.
clipboard.setPrimaryClip(clip);
从剪贴板中粘贴数据
如前所述,要从剪贴板上粘贴数据,首先就要获取全局的剪贴板对象,再获取其中的剪贴对象,查看是否可能从剪贴对象中把数据复制到你自己的存储中。本节详细介绍如果来粘贴这三种格式的剪贴数据。
粘贴纯文本数据
要粘贴纯文本数据,首先要或的全局的剪贴板,并确认它可以返回纯文本。然后获得剪贴对象,并使用getText()方法把数据复制到你自己的存储中,详细过程如下:
1. 使用getSystemService(CLIPBOARD_SERVICE)方法获取全局的ClipboardManager对象。同时声明一个全局变量来保存被粘贴的文本:
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
String pasteData = "";
2. 接下来判断你是否应该开启或禁用当前Activity的”paste”选项。你应该通过剪贴对象所代表的数据类型的确认你是否可以处理剪贴板中所包含的剪贴对象:
// Gets the ID of the "paste" menu item
MenuItem mPasteItem = menu.findItem(R.id.menu_paste);
// If the clipboard doesn't contain data, disable the paste menu item.
// If it does contain data, decide if you can handle the data.
if(!(clipboard.hasPrimaryClip())){
mPasteItem.setEnabled(false);
}elseif(!(clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))){
// This disables the paste menu item, since the clipboard has data but it is not plain text
mPasteItem.setEnabled(false);
}else{
// This enables the paste menu item, since the clipboard contains plain text.
mPasteItem.setEnabled(true);
}
}
3. 从剪贴板中复制数据。只有“paste”菜单项是可用的,程序才可能执行到这里,因此你可以认为剪贴板中包含了纯文本数据。但你依然还不知道剪贴板中包含的似乎纯文本字符串还是指向纯文本的URI。下面的代码判断对其进行了检查,但只显示了对纯文本数据的处理:
// Responds to the user selecting "paste"
case R.id.menu_paste:
// Examines the item on the clipboard. If getText() does not return null, the clip item contains the
// text. Assumes that this application can only handle one item at a time.
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
// Gets the clipboard as text.
pasteData = item.getText();
// If the string contains data, then the paste operation is done
if(pasteData !=null){
return;
// The clipboard does not contain text. If it contains a URI, attempts to get data from it
}else{
Uri pasteUri = item.getUri();
// If the URI contains something, try to get text from it
if(pasteUri !=null){
// calls a routine to resolve the URI and get data from it. This routine is not
// presented here.
pasteData = resolveUri(Uri);
return;
}else{
// Something is wrong. The MIME type was plain text, but the clipboard does not contain either
// text or a Uri. Report an error.
Log.e("Clipboard contains an invalid data type");
return;
}
}
从内容的URI中粘贴数据
如果ClipData.Item对象包含了一个内容的URI,并你已经确定你可以处理它的MIME类型,那么你就可以创建一个ContentResolver对象,然后调用对应的内容提供器方法来获取数据。
下面介绍如何基于剪贴板上的内容的URI,从内容提供器中获取数据。它要检查来自该提供器的那个MIME类型对于本应用程序是否可用:
1. 声明一个全局变量来保存MIME类型:
// Declares a MIME type constant to match against the MIME types offered by the provider
publicstaticfinalString MIME_TYPE_CONTACT ="vnd.android.cursor.item/vnd.example.contact"
2. 获得全局的剪贴板,还要获得一个内容解析器,以便你可以访问内容提供器:
// Gets a handle to the Clipboard Manager
ClipboardManager clipboard =(ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
// Gets a content resolver instance
ContentResolver cr = getContentResolver();
3. 从剪贴板上获取剪贴对象,并获得它的内容的URI:
// Gets the clipboard data from the clipboard
ClipData clip = clipboard.getPrimaryClip();
if(clip !=null){
// Gets the first item from the clipboard data
ClipData.Item item = clip.getItemAt(0);
// Tries to get the item's contents as a URI
Uri pasteUri = item.getUri();
4. 通过调用getType(Uri)方法来测试该URI是否是内容的URI。如果该方法返回null,那么它就不会指向一个可用的内容提供器:
// If the clipboard contains a URI reference
if(pasteUri !=null){
// Is this a content URI?
String uriMimeType = cr.getType(pasteUri);
5. 测试当前应用程序是否理解内容提供所支持的MIME类型,如果理解,就调用ContentResolver.query()方法来获取数据。这个方法的返回值是Cursor:
// If the return value is not null, the Uri is a content Uri
if(uriMimeType !=null){
// Does the content provider offer a MIME type that the current application can use?
if(uriMimeType.equals(MIME_TYPE_CONTACT)){
// Get the data from the content provider.
Cursor pasteCursor = cr.query(uri,null,null,null,null);
// If the Cursor contains data, move to the first record
if(pasteCursor !=null){
if(pasteCursor.moveToFirst()){
// get the data from the Cursor here. The code will vary according to the
// format of the data model.
}
}
// close the Cursor
pasteCursor.close();
}
}
}
}
粘贴Intent对象
要粘贴一个Intent对象,首先要获得全局的剪贴板。调用getIntent()方法来检查ClipData.Item对象中是否包含Intent对象。如果包含则把该Intent对象复制到你自己存储器中,如:
// Gets a handle to the Clipboard Manager
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
// Checks to see if the clip item contains an Intent, by testing to see if getIntent() returns null
Intent pasteIntent = clipboard.getPrimaryClip().getItemAt(0).getIntent();
if (pasteIntent != null) {
// handle the Intent
} else {
// ignore the clipboard, or issue an error if your application was expecting an Intent to be
// on the clipboard
}