Android中資料的複製和貼上的實現粗解
通過標題你就可以猜到,本篇部落格並不會介紹Android中資料複製和貼上的原始碼實現流程、邏輯架構等,我只是根據google提供的文件稍微整理一下,平常基本上是用不到的,有什麼不對的地方,勞煩各位大聲指出!!
文字的複製和貼上將由ClipboardManager進行管理(預設的InputView是支援貼上複製的),它提供多種資料型別的拷貝和貼上,包括文字、複雜的資料結構、二進位制資料流等;其中剪貼簿是有系統持有的,剪貼簿在同一時刻只能持有一個ClipData,當然一個ClipData裡面可以包含過個ClipData.Item,其實真實的資料由ClipData.Item持有的;在使用Intent作為ClipData的資料體時,被貼上的應用將由於這個Intent指向的應用的快捷鍵!!!(沒有試過)
在Android系統中專門有一個系統服務負責資料的複製和貼上的,他就是ClipBoardManager,當然了,這個Manager只是對內部的Service進行封裝之後暴露給開發者的介面。獲取ClipBoardManager的例項物件很簡單,Android系統中幾乎所有的Manager例項都是通過這種方法獲取的:
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
一個ClipData包含一個ClipDescription和至少一個ClipData.Item物件。ClipDescription包含帶貼上的元資料和一個關於有效MIME的陣列,ClipData.Item.coerceToText()使用此方法可以強行將剪貼簿上的資料轉換成一個CharSequence物件,其中Intennt會被轉換成一個Intent的URI物件,然後通過使用URI轉換成字串。
複製文字:
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("simple text","Hello, World!");
clipboard .setPrimaryClip(clip);
貼上文字:
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
if(clipboard.hasPrimaryClip() && clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))){
ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
pasteData = item.getText();//獲取純文字資料
//Uri pasteUri = item.getUri();//獲取URI,然後從根據Uri獲取資料
}
複製URI:
private static final String CONTACTS = "content://com.example.contacts";
private static final String COPY_PATH = "/copy";
...
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
Uri copyUri = Uri.parse(CONTACTS + COPY_PATH + "/" + lastName);
ClipData clip = ClipData.newUri(getContentResolver(),"URI",copyUri);
clipboard .setPrimaryClip(clip);
貼上URI:
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
if(clipboard.hasPrimaryClip()){
ClipData clip = clipboard.getPrimaryClip();
if (clip != null) {
ClipData.Item item = clip.getItemAt(0);
Uri pasteUri = item.getUri();
if (pasteUri != null) {
String uriMimeType = cr.getType(pasteUri);
if (uriMimeType != null) {
if (uriMimeType.equals(MIME_TYPE_CONTACT)) {
Cursor pasteCursor = cr.query(uri, null, null, null, null);
if (pasteCursor != null) {
if (pasteCursor.moveToFirst()) {
//對獲取的資料進行處理,顯示或者儲存等
}
}
}
pasteCursor.close();
}
}
}
}
複製Intent:
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
Intent appIntent = new Intent(this, com.example.demo.myapplication.class);
ClipData clip = ClipData.newIntent("Intent",appIntent);
clipboard .setPrimaryClip(clip);
貼上Intent:
//這個貼上與純文字貼上類似:
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
Intent pasteIntent = clipboard.getPrimaryClip().getItemAt(0).getIntent();
if (pasteIntent != null) {
//處理獲取到的Intent
}
通過使用ContentProvider貼上複製複雜資料:
需要新增一個用於copy的URI,並將這個URI新增至COntentProvider的getType方法,在ClipData呼叫newUri方法時會呼叫getType方法,並將返回的一個String用於表示這個URI表示的MIME。
//以下是原始碼:
static public ClipData newUri(ContentResolver resolver, CharSequence label,
Uri uri) {
Item item = new Item(uri);
String[] mimeTypes = null;
if ("content".equals(uri.getScheme())) {
String realType = resolver.getType(uri);
mimeTypes = resolver.getStreamTypes(uri, "*/*");
if (realType != null) {
if (mimeTypes == null) {
mimeTypes = new String[] { realType };
} else {
String[] tmp = new String[mimeTypes.length + 1];
tmp[0] = realType;
System.arraycopy(mimeTypes, 0, tmp, 1, mimeTypes.length);
mimeTypes = tmp;
}
}
}
if (mimeTypes == null) {
mimeTypes = MIMETYPES_TEXT_URILIST;
}
return new ClipData(label, mimeTypes, item);
}
使用ClipboardManager 的注意事項:
1、ClipBorad這同一時刻只能儲存一個ClipData,只儲存最新的ClipData。
2、不要複製多種型別資料的混合體
3、在使用ContentProvider最好另外定義一個Uri用以表示copy資料的Uri。
4、當MIME檢測都不匹配時,可以將內容強制轉換成純文字的內容。
好了,關於Android系統的ClipboardManager就介紹到這裡,有興趣的朋友可以以關注我,遇到問題大家一起討論一下!!
這是我的微信公眾號,如果可以的話,希望您可以幫忙關注一下,這將是對我最大的鼓勵了,謝謝!!