Clipboard 還能玩出花

Clipboard還能玩出花

Clipboard是Android提供的一個系統服務,它提供了一個全局的剪貼板,讓文字、圖片、數據,在多App間共享成爲可能,今天,咱們來了解下它的真面目,以及被玩壞的新姿式。javascript

老規矩,Google API文檔鎮樓:
developer.android.com/guide/topic…html

說實話,若是不是爲了讓Clipboard玩出花,我真不想寫這一篇,由於——這文檔寫的真是太TM詳細了。java

Clipboard應用

咱們先來看看一些App對Clipboard的應用,例如手機迅雷,若是你複製了一個連接,那麼打開迅雷後,會自動檢測並提示下載:android

再例如一些翻譯軟件,例若有道詞典、滬江小D,他們都有一個功能,即複製查詞,使用的也是這個原理,我這沒裝這些App,就不截圖了,再例如比較經常使用的手淘喵口令,實際上也是利用這個功能,固然,也有一些比較專業的Clipboard App,例如Clipboard Actions:算法

咱們能夠看見,實際上,他就是幫你解析了各類可能的剪貼板,並對他們提供了各類後續功能的集合,確實很是實用,不過,看完今天的文章,相信你要寫一個這樣的App,估計也就分分鐘。app

OK,這些就是一些Clipboard的基本使用場景,更多場景,沒有作不到,只有想不到。ide

基本使用

Clipboard的基本使用,就是三部曲。ui

得到ClipboardManager:this

ClipboardManager mClipboardManager = mClipboardManager = 
(ClipboardManager) getSystemService(CLIPBOARD_SERVICE);複製代碼

Copy:spa

ClipData mClipData;
String text = "hello world";
mClipData = ClipData.newPlainText("test", text);
mClipboardManager.setPrimaryClip(mClipData);複製代碼

Paste:

ClipData clipData = mClipboardManager.getPrimaryClip();
ClipData.Item item = clipData.getItemAt(0);
String text = item.getText().toString();複製代碼

結束了,簡直不能再簡單,API文檔也寫的很是詳細,Demo都寫了好幾個。

不止於文字

咱們能夠建立如下三種類型的ClipData:

類型 描述
Text newPlainText(label, text) 返回ClipData對象,其中ClipData.Item對象包含一個String
URI newUri(resolver, label, URI) 返回ClipData對象,其中ClipData.Item對象包含一個URI
Intent newIntent(label, intent) 返回ClipData對象,其中ClipData.Item對象包含一個Intent

對應的,咱們也能獲取到不一樣類型的ClipData。

ClipboardManager管理

ClipboardManager中有不少判斷與操做方法:

類型 描述
getPrimaryClip() 返回剪貼板上的當前Copy內容
getPrimaryClipDescription() 返回剪貼板上的當前Copy的說明
hasPrimaryClip() 若是當前剪貼板上存在Copy返回True
setPrimaryClip(ClipData clip) 設置剪貼板上的當前Copy
setText(CharSequence text) 設置文本到當前Copy
getText() 獲取剪貼板複製的文本

玩出一朵小FaFa

在瞭解了上面這些內容後,咱們就能夠作一些比較有意思的東西了,例如,咱們能夠經過監控用戶剪貼板中的內容,來作一些自動的推斷,例如,用戶複製了一個英文單詞,那麼咱們能夠推斷,用戶可能要進行翻譯,再例如,用戶複製了一個連接,那麼咱們也能夠推斷,用戶可能須要打開這個連接,等等。

Google在文檔中,直接給出了示例的代碼:

// 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;
    }
}複製代碼

其實很是簡單,就是判斷三種複製類型,可是咱們能夠在App中設置一些相似Scheme的標記,用來進行一些功能的區分,就好像淘寶的喵口令——『喵口令XXXXXXX喵口令』,咱們能夠經過解析這些Scheme,來獲取內容,並進行對應的操做。這也是咱們前面提到的Clipboard Actions這個App作的事情。

玩出一朵大FaFa

咱們首先來看ClipData.Item.coerceToText()這樣一個方法,這個方法能夠將剪貼板裏面的內容,直接轉化爲文字,可是這個轉換,是有必定算法的,在API文檔中有比較詳細的說明,這裏簡單的看下:

這個東西能幹什麼呢,咱們知道,有些App會複製以後,打開一個Intent,爲了簡單,會直接經過ClipData.Item.coerceToText()來返回一個Intent的URI,而後經過解析URI來啓動Intent,那麼這裏就能夠被咱們來利用了。

public void fakeClipboard() {
    // 添加一個假的Intent,模擬用戶最新加入的剪貼板內容
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.hjwordgames", "com.hjwordgames.Splash"));
    intent.setAction("android.intent.action.VIEW");
    ClipData setClipData;
    setClipData = ClipData.newIntent("intent", intent);
    mClipboardManager.setPrimaryClip(setClipData);

    // 呵呵噠 App覺得獲取的是本身須要的Intent,結果卻被狸貓換太子
    ClipData clipData = mClipboardManager.getPrimaryClip();
    ClipData.Item myItem;
    myItem = clipData.getItemAt(0);
    String clipDataString = myItem.coerceToText(this.getApplicationContext()).toString();
    try {
        Intent myIntent = Intent.parseUri(clipDataString, 0);
        startActivity(myIntent);
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
}複製代碼

其實不必定是經過Fake Intent,其它的文字、圖片等等,均可以被『偷天換日』。

另外,要實現這個監聽,咱們須要註冊一個回調——addPrimaryClipChangedListener,Android真是體貼到沒朋友:

mClipboardManager.addPrimaryClipChangedListener(new ClipboardManager.OnPrimaryClipChangedListener() {
    @Override
    public void onPrimaryClipChanged() {
        Log.d("xys", "onPrimaryClipChanged: ");
    }
});複製代碼

那麼在這裏,咱們就能夠徹底實現剪貼板的『狸貓換太子』。那麼假如咱們是一個『某淘』軟件的競品,那麼徹底可讓『汪口令』失效,甚至替換爲咱們本身的應用,同理,還有一些翻譯類軟件也是同樣,不過還好,也許是個人心裏比較陰暗,目前尚未看見這樣的App。

歡迎關注個人公衆號:

相關文章
相關標籤/搜索