Android复制粘贴详解

一、复制与粘贴框架

1.概览

Android提供了一个基于剪切板的复制粘贴框架。支持字符串、复杂数据结构、文本与二进制数据流,以及应用assets的剪切。只有文本可直接存储到剪切板,其他存储为content provider。剪切板支持Text、URI、Intent三种形式的剪切对象。看到这三个,就大概知道了该怎么解析出需要的数据了。剪切板一次仅存储一个剪切对象,再存储另一个,之前的则会消失。

2.重要类与方法

类:

ClipboardManager:代表系统剪切板,通过getSystemService(CLIPBOARD_SERVICE)来获取实例。

ClipData:剪切板一次只包含一个ClipData,ClipData包含一个ClipDescription以及若干个ClipData.Item。

ClipDescription:包含关于剪切的元数据。包含了一组关于剪切数据的MIME类型。

ClipData.Item:包含文本(字符串),URI(一般是content provider URI),Intent(应用快捷方式)。

方法:

newPlainText(label, text):返回ClipData,有一个ClipData.Item,包含一个字符串。ClipDescription对象label属性即为label参数。其MIME

类型为MIMETYPE_TEXT_PLAIN;

newUri(resolver, lable, URI):返回ClipData,有一个ClipData.Item,包含一个URI。label与上述一样,如果URI是content URI,方法使用resolver从content provider获取MIME类型并存储在ClipDescription中。如果不是content URI,其MIME类型则为MIMETYPE_TEXT_URILIST;

newIntent(label, intent):返回ClipData,有一个ClipData.Item,包含一个Intent。label与上述一样,MIME类型为MIMETYPE_TEXT_INTENT。

ClipData.Item.coerceToText():将ClipData.Item中的数据强转为text。具体如下:

如果本身就是Text,则返回该Text;

如果是URI,a.如果是content URI且provider可以返回text stream,则返回text stream;b.如果是content URI,但没有text stream,则返回URI.toString();c.如果不是content URI,也返回URI.toString()。

如果是Intent,将会强转为Intent URI并返回,即Intent.toUri(URI_INTENT_SCHEME)。

具体的剪切板框架如下图所示。

3.剪切板框架原理


复制数据时,将ClipData对象放到ClipboardManager全局剪切板上。其包含了若干ClipData.Item以及一个ClipDescription。

粘贴数据时,应用获取ClipData,再获从ClipDescription获取其MIME类型,之后可以从ClipData.Item或者被其引用的content provider获取数据。

二、使用

1.复制

// 获取clipboard service句柄
ClipboardManager clipboard = (ClipboardManager)
        getSystemService(Context.CLIPBOARD_SERVICE);

// 复制文本
ClipData clip = ClipData.newPlainText("simple text", "Hello, World!");

// 创建Uri,本例中是联系人记录ID以及名称URI
private static final String CONTACTS = "content://com.example.contacts";
private static final String COPY_PATH = "/copy";
Uri copyUri = Uri.parse(CONTACTS + COPY_PATH + "/" + lastName);

// 复制URI对象。使用匿名getContentResolver()对象从provider中获取MIME类型
ClipData clip = ClipData.newUri(getContentResolver(), "URI", copyUri);

// 创建Intent
Intent appIntent = new Intent(this, com.example.demo.myapplication.class);
// 复制Intent对象,设置Intet
ClipData clip = ClipData.newIntent("Intent", appIntent);

// 设置剪切板主要剪辑
clipboard.setPrimaryClip(clip);

2.粘贴

1)获取ClipboardManager service

ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
String pasteData = "";

2)根据剪切板是否含有数据以及数据类型是否可处理,决定是否启用粘贴

// 获取粘贴按钮
MenuItem mPasteItem = menu.findItem(R.id.menu_paste);

// 如果剪切板不包含数据,则禁用粘贴按钮,如果包含数据,要判断是否可以处理
if (!(clipboard.hasPrimaryClip())) {
    mPasteItem.setEnabled(false);
} else if (!(clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN))) {
    // 如果有数据,但是不是文本,则不可粘贴
    mPasteItem.setEnabled(false);
} else {
    // 如果有数据且是文本,则可粘贴
    mPasteItem.setEnabled(true);
}

3)粘贴文本

// 检查item,如果getText不为空,则包含文本。
 ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
// 获取文本
pasteData = item.getText();

// 如果存在文本则粘贴可以进行
if (pasteData != null) {
    return;
// 如果存在的是URI,就要看其是否包含数据 If it contains a URI, attempts to get data from it
} else {
    Uri pasteUri = item.getUri();
    // 如果包含信息,则尝试从中获取文本
    if (pasteUri != null) {
        // 解析URI,获取数据
        pasteData = resolveUri(Uri);
        return;
    } else {
    // 没有信息,如果MIME是文本类型,但是不包含文本或Uri,则提示错误
    Log.e("Clipboard contains an invalid data type");
    return;
    }
}

4)粘贴content URI

// 声明一个匹配provider提供的MIME类型的常量
public static final String MIME_TYPE_CONTACT = "vnd.android.cursor.item/vnd.example.contact";

ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);

// 获取ContentResolver
ContentResolver cr = getContentResolver();
// 从剪切板获取clipboardData
ClipData clip = clipboard.getPrimaryClip();

if (clip != null) {
    // 获取clipboardData的第一个item
    ClipData.Item item = clip.getItemAt(0);
    // 尝试获取Uri
    Uri pasteUri = item.getUri();
    // 如果存在Uri
    if (pasteUri != null) {
        // 如果存在content Uri
        String uriMimeType = cr.getType(pasteUri);
        if (uriMimeType != null) {
            // 判断其MIME类型是否当前应用可用
            if (uriMimeType.equals(MIME_TYPE_CONTACT)) {
                // 从content provider获取数据.
                Cursor pasteCursor = cr.query(uri, null, null, null, null);
                if (pasteCursor != null) {
                    if (pasteCursor.moveToFirst()) {
                    // 获取数据
                    }
                }
                pasteCursor.close();
             }
         }
     }
}

5)粘贴Intent

ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
// 检测clip是否包含Intent
Intent pasteIntent = clipboard.getPrimaryClip().getItemAt(0).getIntent();

if (pasteIntent != null) {
    // 处理Intent
} else {
    // ...
}

3.附加

一般应用只需要复制粘贴文本的功能,这里有一个工具:

public class ClipboardUtils {

    public static final String DATA = "data";

    /**
     * 复制到剪切板
     * @param context context
     * @param label 标签
     * @param string 内容
     */
    public static void copy(Context context, String label, String string) {
        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        clipboardManager.setPrimaryClip(ClipData.newPlainText(label != null ? label : DATA, string));
    }

    /**
     * 从剪切板取出
     * @param context context
     * @return 剪切板里的内容
     */
    public static String paste(Context context) {
        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clipData = clipboardManager.getPrimaryClip();
        return clipData.getItemAt(0).toString();
    }

}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 剪贴板是一种系统级别的服务,它可以让用户在不同的应用程序之间复制和粘贴文本、图像等数据。在 Android 系统中,剪贴板分为两种类型:系统剪贴板和应用剪贴板。 系统剪贴板是全局的,可以被所有应用程序访问。它通常用于在不同的应用程序之间复制和粘贴数据。在 Android 系统中,系统剪贴板中的数据可以是文本、URI、Intent 等类型。 应用剪贴板是应用程序自己定义的剪贴板,用于在应用程序内部复制和粘贴数据。应用剪贴板只能被应用程序自己访问,其他应用程序无法访问它。应用剪贴板可以包含任何类型的数据,如文本、图像、音频、视频等。 Android 系统提供了一些 API 来访问系统剪贴板和应用剪贴板。以下是一些常用的 API: 1. getPrimaryClip():获取系统剪贴板中的数据。 2. setPrimaryClip():向系统剪贴板中写入数据。 3. addPrimaryClipChangedListener():注册一个监听器,当系统剪贴板中的数据发生变化时,可以收到通知。 4. getClipboardManager():获取应用程序的剪贴板管理器。 5. setText():向应用程序的剪贴板中写入文本数据。 6. getText():从应用程序的剪贴板中获取文本数据。 7. hasPrimaryClip():检查系统剪贴板中是否有数据。 Android 剪贴板的使用非常方便,可以让用户在不同的应用程序之间轻松地复制和粘贴数据,提高了用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值