Android剪切板标签,Android剪切板

介绍

Android提供了一个强大的基于剪贴板的复制和粘贴框架。它既支持简单的数据类型,也支持复杂的数据类型,包括文本字符串、复杂的数据结构、文本和二进制流数据,甚至还支持应用程序资源。

如下图所示:

7d488a9d3f3e?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

clip.png

由上图可以简单的得到Android剪切板模版主要由四个类构成:ClipboardManager、ClipData、ClipData.Item、ClipDescription.

简单的描述:系统复制数据,就是创建一个ClipData对象放在ClipboardManager全局上.ClipData可以包括多条Item子数据,子数据中复制内容可以是text,url,intent,但是都是这些子数据都是来自一次复制,每次复制会覆盖之前的复制内容.同时,ClipData中包含一个ClipDescription,用于描述本次复制内容的MimeType.

核心类

ClipboardManager

系统服务全局的剪切板类.如何得到如下:

ClipboardManager mClipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);

定义当剪贴板上的主剪辑发生更改时调用的侦听器回调:OnPrimaryClipChangedListener.

// 添加剪贴板数据改变监听器

mClipboardManager.addPrimaryClipChangedListener(new ClipboardManager.OnPrimaryClipChangedListener() {

@Override

public void onPrimaryClipChanged() {

// 剪贴板中的数据被改变,此方法将被回调

System.out.println("onPrimaryClipChanged()");

}

});

// 移除指定的剪贴板数据改变监听器

mClipboardManager.removePrimaryClipChangedListener(listener);

ClipData.Item

剪切板子数据类,它包含了text、html、Uri或者Intent数据,一个clip对象可以包含一个或多个Item对象。

一起来看看它的属性:

final CharSequence mText;

final String mHtmlText;

final Intent mIntent;

Uri mUri;

就是一个数据类.

ClipDescription

剪切板的描述类.包含了ClipData对象的metadata信息,一般情况mimeType只有一个.

一起看看它的属性就知道干什么的类了.

public class ClipDescription implements Parcelable {

//默认的MimeTYpe

public static final String MIMETYPE_TEXT_PLAIN = "text/plain";

public static final String MIMETYPE_TEXT_HTML = "text/html";

public static final String MIMETYPE_TEXT_URILIST = "text/uri-list";

public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";

public static final String EXTRA_TARGET_COMPONENT_NAME =

"android.content.extra.TARGET_COMPONENT_NAME";

public static final String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";

//包含一个标签

final CharSequence mLabel;

//mimeType数组

final String[] mMimeTypes;

//可以保存额外的数据

private PersistableBundle mExtras;

......

}

一般使用前面四种:text、html、uri、intent.其中url比较特殊.如果使用Android资源MimeType需要由ContentResolver提供.

什么是uri:

通用资源标志符(Universal Resource Identifier, 简称"URI")。

Uri代表要操作的数据,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。

Android的Uri由以下三部分组成: "content://"、数据的路径、标示ID(可选)

ClipData

剪切对象,在有且仅有一个剪切板对象在系统服务中.言外之意,每一次复制前一次复制内容都会消失.

一起来看看它的属性:

public class ClipData implements Parcelable {

//默认mimetype。 text/plain

static final String[] MIMETYPES_TEXT_PLAIN = new String[] {

ClipDescription.MIMETYPE_TEXT_PLAIN };

//text/html

static final String[] MIMETYPES_TEXT_HTML = new String[] {

ClipDescription.MIMETYPE_TEXT_HTML };

//urllist

static final String[] MIMETYPES_TEXT_URILIST = new String[] {

ClipDescription.MIMETYPE_TEXT_URILIST };

//intent

static final String[] MIMETYPES_TEXT_INTENT = new String[] {

ClipDescription.MIMETYPE_TEXT_INTENT };

//剪切板描述类

final ClipDescription mClipDescription;

final Bitmap mIcon;

//用于存放剪切板子数据

final ArrayList mItems;

.......

}

创建方式:

/**

* Create a new ClipData holding data of the type

* {@link ClipDescription#MIMETYPE_TEXT_PLAIN}.

*

* @param label User-visible label for the clip data.

* @param text The actual text in the clip.

* @return Returns a new ClipData containing the specified data.

*/

static public ClipData newPlainText(CharSequence label, CharSequence text) {

Item item = new Item(text);

return new ClipData(label, MIMETYPES_TEXT_PLAIN, item);

}

/**

* Create a new ClipData holding data of the type

* {@link ClipDescription#MIMETYPE_TEXT_HTML}.

*

* @param label User-visible label for the clip data.

* @param text The text of clip as plain text, for receivers that don't

* handle HTML. This is required.

* @param htmlText The actual HTML text in the clip.

* @return Returns a new ClipData containing the specified data.

*/

static public ClipData newHtmlText(CharSequence label, CharSequence text,

String htmlText) {

Item item = new Item(text, htmlText);

return new ClipData(label, MIMETYPES_TEXT_HTML, item);

}

/**

* Create a new ClipData holding an Intent with MIME type

* {@link ClipDescription#MIMETYPE_TEXT_INTENT}.

*

* @param label User-visible label for the clip data.

* @param intent The actual Intent in the clip.

* @return Returns a new ClipData containing the specified data.

*/

static public ClipData newIntent(CharSequence label, Intent intent) {

Item item = new Item(intent);

return new ClipData(label, MIMETYPES_TEXT_INTENT, item);

}

/**

* Create a new ClipData holding a URI. If the URI is a content: URI,

* this will query the content provider for the MIME type of its data and

* use that as the MIME type. Otherwise, it will use the MIME type

* {@link ClipDescription#MIMETYPE_TEXT_URILIST}.

*

* @param resolver ContentResolver used to get information about the URI.

* @param label User-visible label for the clip data.

* @param uri The URI in the clip.

* @return Returns a new ClipData containing the specified data.

*/

static public ClipData newUri(ContentResolver resolver, CharSequence label,

Uri uri) {

//创建item

Item item = new Item(uri);

/*获取mimeType*/

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);

}

/**

* Create a new ClipData holding an URI with MIME type

* {@link ClipDescription#MIMETYPE_TEXT_URILIST}.

* Unlike {@link #newUri(ContentResolver, CharSequence, Uri)}, nothing

* is inferred about the URI -- if it is a content: URI holding a bitmap,

* the reported type will still be uri-list. Use this with care!

*

* @param label User-visible label for the clip data.

* @param uri The URI in the clip.

* @return Returns a new ClipData containing the specified data.

*/

static public ClipData newRawUri(CharSequence label, Uri uri) {

//创建item

Item item = new Item(uri);

return new ClipData(label, MIMETYPES_TEXT_URILIST, item);

}

clipData对象创建后塞入Clipboardmanager即可:

//Clipboardmanager方法

/**

* Sets the current primary clip on the clipboard. This is the clip that

* is involved in normal cut and paste operations.

*

* @param clip The clipped data item to set.

*/

public void setPrimaryClip(ClipData clip) {

try {

if (clip != null) {

clip.prepareToLeaveProcess(true);

}

getService().setPrimaryClip(clip, mContext.getOpPackageName());

} catch (RemoteException e) {

throw e.rethrowFromSystemServer();

}

}

转换成字符串

//任何作为HTML格式返回的文本都将作为具有样式跨度的文本返回。

CharSequence coerceToStyledText(Context context);

//如果getText()是非空的,则返回该值。

//如果getUri()非null,则尝试从其内容提供程序检索其数据作为文本流。如果成功,将文本复制到字符串中并返回。如果它不是内容:URI或内容提供程序不提供文本表示,则将原始URI作为字符串返回。

//如果getIntent()非null,则将其转换为intent: URI并返回。

//否则,返回一个空字符串。

CharSequence coerceToText(Context context) ;

//如果getHtmlText()非null,则返回该值。

//如果getText()是非空的,返回它,转换为有效的HTML文本。如果此文本包含样式跨度,则使用HTML . tohtml (span)将其转换为HTML格式。

//如果getUri()非null,则尝试从其内容提供程序检索其数据作为文本流。

//如果提供程序可以提供文本/html数据,则首选该数据并按原样返回。否则,将返回任何文本/*数据并转义到HTML。

//如果它不是内容:URI或内容提供程序不提供文本表示,将返回包含到URI链接的HTML文本。

//如果getIntent()非null,则将其转换为intent: URI并以HTML链接的形式返回。

//否则,返回一个空字符串。

String coerceToHtmlText(Context context)

详细的内容可以查看官网,地址我也写出来了,在最下面,哈哈哈.

注意

1、剪切板只会保存最近一次复制的内容.

2、MimeType一般只有一个.(可以有多个)

3、系统全局的剪切板,其他应用也可以使用.

工具类

package com.rnx.react.modules.clip;

import android.content.ClipData;

import android.content.ClipDescription;

import android.content.ClipboardManager;

import android.content.ContentResolver;

import android.content.Context;

import android.content.Intent;

import android.net.Uri;

import java.util.List;

/**

* @Auther: weiwei.zhang06

* @Date: 2018/12/5 18:59

*/

public class ClipboardHelper {

public static final String TAG = ClipboardHelper.class.getSimpleName();

private Context mContext;

private volatile static ClipboardHelper mInstance;

private ClipboardManager mClipboardManager;

private ClipboardHelper(Context context) {

mContext = context;

mClipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);

}

/**

* 获取ClipboardUtil实例,记得初始化

*

* @return 单例

*/

public static ClipboardHelper getInstance(Context context) {

if (mInstance == null) {

synchronized (ClipboardHelper.class) {

if (mInstance == null) {

mInstance = new ClipboardHelper(context.getApplicationContext());

}

}

}

return mInstance;

}

/**

* 判断剪贴板内是否有数据

*

* @return

*/

public boolean hasPrimaryClip() {

return mClipboardManager.hasPrimaryClip();

}

/**

* 获取剪贴板中第一条String

*

* @return

*/

public String getClipText() {

if (!hasPrimaryClip()) {

return null;

}

ClipData data = mClipboardManager.getPrimaryClip();

if (data != null

&& mClipboardManager.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {

return data.getItemAt(0).getText().toString();

}

return null;

}

/**

* 获取剪贴板中第一条String

*

* @param context

* @return

*/

public String getClipText(Context context) {

return getClipText(context, 0);

}

/**

* 获取剪贴板中指定位置item的string

*

* @param context

* @param index

* @return

*/

public String getClipText(Context context, int index) {

if (!hasPrimaryClip()) {

return null;

}

ClipData data = mClipboardManager.getPrimaryClip();

if (data == null) {

return null;

}

if (data.getItemCount() > index) {

return data.getItemAt(index).coerceToText(context).toString();

}

return null;

}

/**

* 将文本拷贝至剪贴板

*

* @param text

*/

public void copyText(String label, String text) {

ClipData clip = ClipData.newPlainText(label, text);

mClipboardManager.setPrimaryClip(clip);

}

/**

* 将HTML等富文本拷贝至剪贴板

*

* @param label

* @param text

* @param htmlText

*/

public void copyHtmlText(String label, String text, String htmlText) {

ClipData clip = ClipData.newHtmlText(label, text, htmlText);

mClipboardManager.setPrimaryClip(clip);

}

/**

* 将Intent拷贝至剪贴板

*

* @param label

* @param intent

*/

public void copyIntent(String label, Intent intent) {

ClipData clip = ClipData.newIntent(label, intent);

mClipboardManager.setPrimaryClip(clip);

}

/**

* 将Uri拷贝至剪贴板

* If the URI is a content: URI,

* this will query the content provider for the MIME type of its data and

* use that as the MIME type. Otherwise, it will use the MIME type

* {@link ClipDescription#MIMETYPE_TEXT_URILIST}.

* 如 uri = "content://contacts/people",那么返回的MIME type将变成"vnd.android.cursor.dir/person"

*

* @param cr ContentResolver used to get information about the URI.

* @param label User-visible label for the clip data.

* @param uri The URI in the clip.

*/

public void copyUri(ContentResolver cr, String label, Uri uri) {

ClipData clip = ClipData.newUri(cr, label, uri);

mClipboardManager.setPrimaryClip(clip);

}

/**

* 将多组数据放入剪贴板中,如选中ListView多个Item,并将Item的数据一起放入剪贴板

*

* @param label User-visible label for the clip data.

* @param mimeType mimeType is one of them:{@link ClipDescription#MIMETYPE_TEXT_PLAIN},

* {@link ClipDescription#MIMETYPE_TEXT_HTML},

* {@link ClipDescription#MIMETYPE_TEXT_URILIST},

* {@link ClipDescription#MIMETYPE_TEXT_INTENT}.

* @param items 放入剪贴板中的数据

*/

public void copyMultiple(String label, String mimeType, List items) {

if (items == null || items.size() == 0) {

throw new IllegalArgumentException("argument: items error");

}

int size = items.size();

ClipData clip = new ClipData(label, new String[]{mimeType}, items.get(0));

for (int i = 1; i < size; i++) {

clip.addItem(items.get(i));

}

mClipboardManager.setPrimaryClip(clip);

}

public void copyMultiple(String label, String[] mimeTypes, List items) {

if (items == null || items.size() == 0) {

throw new IllegalArgumentException("argument: items error");

}

int size = items.size();

ClipData clip = new ClipData(label, mimeTypes, items.get(0));

for (int i = 1; i < size; i++) {

clip.addItem(items.get(i));

}

mClipboardManager.setPrimaryClip(clip);

}

public CharSequence coercePrimaryClipToText() {

if (!hasPrimaryClip()) {

return null;

}

return mClipboardManager.getPrimaryClip().getItemAt(0).coerceToText(mContext);

}

public CharSequence coercePrimaryClipToStyledText() {

if (!hasPrimaryClip()) {

return null;

}

return mClipboardManager.getPrimaryClip().getItemAt(0).coerceToStyledText(mContext);

}

public CharSequence coercePrimaryClipToHtmlText() {

if (!hasPrimaryClip()) {

return null;

}

return mClipboardManager.getPrimaryClip().getItemAt(0).coerceToHtmlText(mContext);

}

/**

* 获取当前剪贴板内容的MimeType

*

* @return 当前剪贴板内容的MimeType

*/

public String getPrimaryClipMimeType() {

if (!hasPrimaryClip()) {

return null;

}

return mClipboardManager.getPrimaryClipDescription().getMimeType(0);

}

/**

* 获取剪贴板内容的MimeType

*

* @param clip 剪贴板内容

* @return 剪贴板内容的MimeType

*/

public String getClipMimeType(ClipData clip) {

return clip.getDescription().getMimeType(0);

}

/**

* 获取剪贴板内容的MimeType

*

* @param clipDescription 剪贴板内容描述

* @return 剪贴板内容的MimeType

*/

public String getClipMimeType(ClipDescription clipDescription) {

return clipDescription.getMimeType(0);

}

/**

* 清空剪贴板

*/

public void clearClip() {

mClipboardManager.setPrimaryClip(ClipData.newPlainText(null, ""));

}

public ClipData getClipData() {

if (!hasPrimaryClip()) {

return null;

}

return mClipboardManager.getPrimaryClip();

}

}

感谢阅读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值