Clipboard还能玩出花

简介: Clipboard是Android提供的一个系统服务,它提供了一个全局的剪贴板,让文字、图片、数据,在多App间共享成为可能,今天,我们来了解下它的真面目,以及被玩坏的新姿势。

Clipboard是Android提供的一个系统服务,它提供了一个全局的剪贴板,让文字、图片、数据,在多App间共享成为可能,今天,我们来了解下它的真面目,以及被玩坏的新姿势。

老规矩,Google API文档镇楼:
https://developer.android.com/guide/topics/text/copy-paste.html

说实话,如果不是为了让Clipboard玩出花,我真不想写这一篇,因为——这文档写的真是太TM详细了。

Clipboard应用

我们先来看看一些App对Clipboard的应用,例如手机迅雷,如果你复制了一个链接,那么打开迅雷后,会自动检测并提示下载:

这里写图片描述

再例如一些翻译软件,例如有道词典、沪江小D,他们都有一个功能,即复制查词,使用的也是这个原理,我这没装这些App,就不截图了,再例如比较常用的手淘喵口令,实际上也是利用这个功能,当然,也有一些比较专业的Clipboard App,例如Clipboard Actions:

这里写图片描述

我们可以看见,实际上,他就是帮你解析了各种可能的剪贴板,并对他们提供了各种后续功能的集合,确实非常实用,不过,看完今天的文章,相信你要写一个这样的App,估计也就分分钟。

OK,这些就是一些Clipboard的基本使用场景,更多场景,没有做不到,只有想不到。

基本使用

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

获得ClipboardManager:

ClipboardManager mClipboardManager = mClipboardManager = 
(ClipboardManager) getSystemService(CLIPBOARD_SERVICE);

Copy:

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。

欢迎大家关注我的公众号:

这里写图片描述

目录
相关文章
|
机器学习/深度学习 人工智能 自然语言处理
【paddlehubOCR项目】网课手酸酸,眼花花,救星来啦!
大家好这里是三岁,今天给大家带来的是在AiStudio项目平台的一个精选项目,虽然很短,但是效果拔群,使用到了最近特别火的paddleOCR~~~
235 0
【paddlehubOCR项目】网课手酸酸,眼花花,救星来啦!
|
程序员 Android开发 iOS开发
程序员五一修图小贴士
程序员五一修图小贴士
123 0
程序员五一修图小贴士
|
前端开发 JavaScript 程序员
2023将至,前端程序员们应该一起放个烟花庆祝一下,走起
前言:小时候,在我印象中,每到快过年的时候就有很多卖炮仗的,一般也就是阳历的12月份到明年的正月15号卖炮仗的商家比较多,省下买辣条的钱去买炮仗,在老家也就过年和除夕两天及正月15日这几天放烟花和炮仗比较猛,现在年纪大了,听不得炮仗那种噪声了,也考虑到环保,工作之后的程序员以代码的形式演绎一下烟花的效果。
225 0
2023将至,前端程序员们应该一起放个烟花庆祝一下,走起
|
Web App开发 JavaScript 前端开发
【程序员的浪漫】七夕到了,还不快给你女朋友做一个专属chrome插件
【程序员的浪漫】七夕到了,还不快给你女朋友做一个专属chrome插件
129 0
【程序员的浪漫】七夕到了,还不快给你女朋友做一个专属chrome插件
|
机器人
同事“带薪摸鱼”的窍门,全藏在这1个办公小技巧里了(RPA)
同事“带薪摸鱼”的窍门,全藏在这1个办公小技巧里了(RPA)
135 0
超火 3D 照片墙,你学废了吗?
超火 3D 照片墙,你学废了吗?
108 0
N900当初的绚丽宣传片
N900虽然已经发布了一年多,但是,它还是NOKIA最具可玩性的一款手机,当初的宣传片也可以看出NOKIA本想大力宣传这款性能强劲的旗舰机型。
642 0
表白这件事,比解 bug 要难多少?
今天是个粉红色日子,我们来聊聊和技术无关的“技术活”
3054 0
|
程序员 Python 数据安全/隐私保护
程序员制作网站告白女朋友
创意版权:容大教育 编辑:潇洒坤 效果图如下,有动画效果: 效果图.jpg 1. 下载python2.7,已经安装python则跳过此步 链接: https://pan.baidu.com/s/1zfuhR8w3DlxsleU6phglBw 密码: ugbx python2很小,只有20M。
1735 0
|
Windows
UWP 记一次WTS 和 UCT翻车经历
原文:UWP 记一次WTS 和 UCT翻车经历 这次翻车,真的,在网上绝对找不到回答的。 只有在WTS的Issues讨论中才找到,哈哈 不过这个应该比较少遇到吧,据我所知,提出Issue那个大胸弟和我都遇到了。
1497 0

相关实验场景

更多