1. 程式人生 > >Android中資料的複製和貼上的實現粗解

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就介紹到這裡,有興趣的朋友可以以關注我,遇到問題大家一起討論一下!!
這是我的微信公眾號,如果可以的話,希望您可以幫忙關注一下,這將是對我最大的鼓勵了,謝謝!!
這裡寫圖片描述