您的位置:首页 > 其它

ClipBoardService剪贴服务:

2013-11-05 10:53 190 查看
主要相关类:

content.ClipboardManager继承于text.ClipBoardManager。说明早期的服务只支持文本。

ClipData像一个容器一样,管理存储在启动的数据信息。具体信息存储在ClipData的成员变量mItems中。

ClipDescription用来描述ClipData中的数据类型。目前只是Text。Intent和URL列表。

服务端有ClipBoardService实现。

1.复制数据:

case R.id.context_copy:
// Gets a handle to the clipboard service.
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);//获取ClipboardManager对象

// Copies the notes URI to the clipboard. In effect, this copies the note itself
clipboard.setPrimaryClip(ClipData.newUri(   // new clipboard item holding a URI
getContentResolver(),               // resolver to retrieve URI info
"Note",                             // label for the clip
noteUri)                            // the URI
//  Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);为你要复制的内容的uri地址
);
ClipData.newUri返回一个存储URI数据类型的ClipData。

static public ClipData newUri(ContentResolver resolver, CharSequence label,
Uri uri) {
Item item = new Item(uri);//将uri直接赋值给Item构造函数
String[] mimeTypes = null;
if ("content".equals(uri.getScheme())) {//获取uri代表的数据的MIEI类型。
String realType = resolver.getType(uri);
mimeTypes = resolver.getStreamTypes(uri, "*/*");//获取MIEI类型
if (mimeTypes == null) {
if (realType != null) {
mimeTypes = new String[] { realType, ClipDescription.MIMETYPE_TEXT_URILIST };
}
} else {
String[] tmp = new String[mimeTypes.length + (realType != null ? 2 : 1)];
int i = 0;
if (realType != null) {
tmp[0] = realType;
i++;
}
System.arraycopy(mimeTypes, 0, tmp, i, mimeTypes.length);
tmp[i + mimeTypes.length] = ClipDescription.MIMETYPE_TEXT_URILIST;
mimeTypes = tmp;
}
}
if (mimeTypes == null) {//如果获取不到,那么指定类型
mimeTypes = MIMETYPES_TEXT_URILIST;
}
return new ClipData(label, mimeTypes, item);//返回一个ClipData对象
}
获取到ClipData之后,会调用setPrimaryClip将数据传递到CBS。

public void setPrimaryClip(ClipData clip) {
try {
getService().setPrimaryClip(clip);//跨binder调用,先要把参数打包
} catch (RemoteException e) {
}
}
有ClipBoardService完成实际功能。

public void setPrimaryClip(ClipData clip) {
synchronized (this) {
if (clip != null && clip.getItemCount() <= 0) {
throw new IllegalArgumentException("No items");
}
checkDataOwnerLocked(clip, Binder.getCallingUid());//检查权限。
clearActiveOwnersLocked();
mPrimaryClip = clip;//保存新的ClipData
final int n = mPrimaryClipListeners.beginBroadcast();
for (int i = 0; i < n; i++) {
try {
//通知客户端,剪贴板的内容发生了变化
mPrimaryClipListeners.getBroadcastItem(i).dispatchPrimaryClipChanged();
} catch (RemoteException e) {

// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
mPrimaryClipListeners.finishBroadcast();
}
}

2.粘贴数据:

private final void performPaste() {
// Gets a handle to the Clipboard Manager
ClipboardManager clipboard = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);

// Gets a content resolver instance
ContentResolver cr = getContentResolver();

// Gets the clipboard data from the clipboard
ClipData clip = clipboard.getPrimaryClip();//去除ClipData
if (clip != null) {

String text=null;
String title=null;

// Gets the first item from the clipboard data
ClipData.Item item = clip.getItemAt(0);//取第一项Item

// Tries to get the item's contents as a URI pointing to a note
Uri uri = item.getUri();

// Tests to see that the item actually is an URI, and that the URI
// is a content URI pointing to a provider whose MIME type is the same
// as the MIME type supported by the Note pad provider.
if (uri != null && NotePad.Notes.CONTENT_ITEM_TYPE.equals(cr.getType(uri))) {

// The clipboard holds a reference to data with a note MIME type. This copies it.
Cursor orig = cr.query(//查询数据库并获取信息
uri,            // URI for the content provider
PROJECTION,     // Get the columns referred to in the projection
null,           // No selection variables
null,           // No selection variables, so no criteria are needed
null            // Use the default sort order
);

// If the Cursor is not null, and it contains at least one record
// (moveToFirst() returns true), then this gets the note data from it.
if (orig != null) {
if (orig.moveToFirst()) {
int colNoteIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE);
int colTitleIndex = mCursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE);
text = orig.getString(colNoteIndex);
title = orig.getString(colTitleIndex);
}

// Closes the cursor.
orig.close();
}
}

// If the contents of the clipboard wasn't a reference to a note, then
// this converts whatever it is to text.
if (text == null) {//如果paste方不了解ClipData的数据类型,那么调用下面方法强制得到文本类型的数据。
text = item.coerceToText(this).toString();
}

// Updates the current note with the retrieved title and text.
updateNote(text, title);
}
}


getPrimaryClip方法在ClipBoardManager中:
public ClipData getPrimaryClip() {
try {
return getService().getPrimaryClip(mContext.getPackageName());
} catch (RemoteException e) {
return null;
}
}
最终调用ClipDataService中的方法:

public ClipData getPrimaryClip(String pkg) {
synchronized (this) {
addActiveOwnerLocked(Binder.getCallingUid(), pkg);//赋值该pkg相应的权限
return mPrimaryClip;
}
}
还有代码中设计到授权管理,比如说你复制一段内容为数据库中的数据,那么复制的时候是复制的uri。那么在粘贴的时候就要判断是否有访问数据库的权限。以防止信息泄露。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: