FileDocCategorySizeDatePackage
ClipData.javaAPI DocAndroid 5.1 API36549Thu Mar 12 22:22:10 GMT 2015android.content

ClipData

public class ClipData extends Object implements android.os.Parcelable
Representation of a clipped data on the clipboard.

ClippedData is a complex type containing one or Item instances, each of which can hold one or more representations of an item of data. For display to the user, it also has a label and iconic representation.

A ClipData contains a {@link ClipDescription}, which describes important meta-data about the clip. In particular, its {@link ClipDescription#getMimeType(int) getDescription().getMimeType(int)} must return correct MIME type(s) describing the data in the clip. For help in correctly constructing a clip with the correct MIME type, use {@link #newPlainText(CharSequence, CharSequence)}, {@link #newUri(ContentResolver, CharSequence, Uri)}, and {@link #newIntent(CharSequence, Intent)}.

Each Item instance can be one of three main classes of data: a simple CharSequence of text, a single Intent object, or a Uri. See {@link Item} for more details.

Developer Guides

For more information about using the clipboard framework, read the Copy and Paste developer guide.

Implementing Paste or Drop

To implement a paste or drop of a ClippedData object into an application, the application must correctly interpret the data for its use. If the {@link Item} it contains is simple text or an Intent, there is little to be done: text can only be interpreted as text, and an Intent will typically be used for creating shortcuts (such as placing icons on the home screen) or other actions.

If all you want is the textual representation of the clipped data, you can use the convenience method {@link Item#coerceToText Item.coerceToText}. In this case there is generally no need to worry about the MIME types reported by {@link ClipDescription#getMimeType(int) getDescription().getMimeType(int)}, since any clip item can always be converted to a string.

More complicated exchanges will be done through URIs, in particular "content:" URIs. A content URI allows the recipient of a ClippedData item to interact closely with the ContentProvider holding the data in order to negotiate the transfer of that data. The clip must also be filled in with the available MIME types; {@link #newUri(ContentResolver, CharSequence, Uri)} will take care of correctly doing this.

For example, here is the paste function of a simple NotePad application. When retrieving the data from the clipboard, it can do either two things: if the clipboard contains a URI reference to an existing note, it copies the entire structure of the note into a new note; otherwise, it simply coerces the clip into text and uses that as the new note's contents. {@sample development/samples/NotePad/src/com/example/android/notepad/NoteEditor.java paste}

In many cases an application can paste various types of streams of data. For example, an e-mail application may want to allow the user to paste an image or other binary data as an attachment. This is accomplished through the ContentResolver {@link ContentResolver#getStreamTypes(Uri, String)} and {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, android.os.Bundle)} methods. These allow a client to discover the type(s) of data that a particular content URI can make available as a stream and retrieve the stream of data.

For example, the implementation of {@link Item#coerceToText Item.coerceToText} itself uses this to try to retrieve a URI clip as a stream of text: {@sample frameworks/base/core/java/android/content/ClipData.java coerceToText}

Implementing Copy or Drag

To be the source of a clip, the application must construct a ClippedData object that any recipient can interpret best for their context. If the clip is to contain a simple text, Intent, or URI, this is easy: an {@link Item} containing the appropriate data type can be constructed and used.

More complicated data types require the implementation of support in a ContentProvider for describing and generating the data for the recipient. A common scenario is one where an application places on the clipboard the content: URI of an object that the user has copied, with the data at that URI consisting of a complicated structure that only other applications with direct knowledge of the structure can use.

For applications that do not have intrinsic knowledge of the data structure, the content provider holding it can make the data available as an arbitrary number of types of data streams. This is done by implementing the ContentProvider {@link ContentProvider#getStreamTypes(Uri, String)} and {@link ContentProvider#openTypedAssetFile(Uri, String, android.os.Bundle)} methods.

Going back to our simple NotePad application, this is the implementation it may have to convert a single note URI (consisting of a title and the note text) into a stream of plain text data. {@sample development/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java stream}

The copy operation in our NotePad application is now just a simple matter of making a clip containing the URI of the note being copied: {@sample development/samples/NotePad/src/com/example/android/notepad/NotesList.java copy}

Note if a paste operation needs this clip as text (for example to paste into an editor), then {@link Item#coerceToText(Context)} will ask the content provider for the clip URI as text and successfully paste the entire note.

Fields Summary
static final String[]
MIMETYPES_TEXT_PLAIN
static final String[]
MIMETYPES_TEXT_HTML
static final String[]
MIMETYPES_TEXT_URILIST
static final String[]
MIMETYPES_TEXT_INTENT
final ClipDescription
mClipDescription
final android.graphics.Bitmap
mIcon
final ArrayList
mItems
public static final Parcelable.Creator
CREATOR
Constructors Summary
public ClipData(CharSequence label, String[] mimeTypes, Item item)
Create a new clip.

param
label Label to show to the user describing this clip.
param
mimeTypes An array of MIME types this data is available as.
param
item The contents of the first item in the clip.

        mClipDescription = new ClipDescription(label, mimeTypes);
        if (item == null) {
            throw new NullPointerException("item is null");
        }
        mIcon = null;
        mItems = new ArrayList<Item>();
        mItems.add(item);
    
public ClipData(ClipDescription description, Item item)
Create a new clip.

param
description The ClipDescription describing the clip contents.
param
item The contents of the first item in the clip.

        mClipDescription = description;
        if (item == null) {
            throw new NullPointerException("item is null");
        }
        mIcon = null;
        mItems = new ArrayList<Item>();
        mItems.add(item);
    
ClipData(android.os.Parcel in)

        mClipDescription = new ClipDescription(in);
        if (in.readInt() != 0) {
            mIcon = Bitmap.CREATOR.createFromParcel(in);
        } else {
            mIcon = null;
        }
        mItems = new ArrayList<Item>();
        final int N = in.readInt();
        for (int i=0; i<N; i++) {
            CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            String htmlText = in.readString();
            Intent intent = in.readInt() != 0 ? Intent.CREATOR.createFromParcel(in) : null;
            Uri uri = in.readInt() != 0 ? Uri.CREATOR.createFromParcel(in) : null;
            mItems.add(new Item(text, htmlText, intent, uri));
        }
    
public ClipData(ClipData other)
Create a new clip that is a copy of another clip. This does a deep-copy of all items in the clip.

param
other The existing ClipData that is to be copied.

        mClipDescription = other.mClipDescription;
        mIcon = other.mIcon;
        mItems = new ArrayList<Item>(other.mItems);
    
Methods Summary
public voidaddItem(android.content.ClipData$Item item)
Add a new Item to the overall ClipData container.

        if (item == null) {
            throw new NullPointerException("item is null");
        }
        mItems.add(item);
    
public intdescribeContents()

        return 0;
    
public voidfixUris(int contentUserHint)

hide

        final int size = mItems.size();
        for (int i = 0; i < size; i++) {
            final Item item = mItems.get(i);
            if (item.mIntent != null) {
                item.mIntent.fixUris(contentUserHint);
            }
            if (item.mUri != null) {
                item.mUri = maybeAddUserId(item.mUri, contentUserHint);
            }
        }
    
public voidfixUrisLight(int contentUserHint)
Only fixing the data field of the intents

hide

        final int size = mItems.size();
        for (int i = 0; i < size; i++) {
            final Item item = mItems.get(i);
            if (item.mIntent != null) {
                Uri data = item.mIntent.getData();
                if (data != null) {
                    item.mIntent.setData(maybeAddUserId(data, contentUserHint));
                }
            }
            if (item.mUri != null) {
                item.mUri = maybeAddUserId(item.mUri, contentUserHint);
            }
        }
    
public ClipDescriptiongetDescription()
Return the {@link ClipDescription} associated with this data, describing what it contains.

        return mClipDescription;
    
public android.graphics.BitmapgetIcon()

hide

        return mIcon;
    
public android.content.ClipData$ItemgetItemAt(int index)
Return a single item inside of the clip data. The index can range from 0 to {@link #getItemCount()}-1.

        return mItems.get(index);
    
public intgetItemCount()
Return the number of items in the clip data.

        return mItems.size();
    
public static android.content.ClipDatanewHtmlText(java.lang.CharSequence label, java.lang.CharSequence text, java.lang.String htmlText)
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.

        Item item = new Item(text, htmlText);
        return new ClipData(label, MIMETYPES_TEXT_HTML, item);
    
public static android.content.ClipDatanewIntent(java.lang.CharSequence label, Intent intent)
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.

        Item item = new Item(intent);
        return new ClipData(label, MIMETYPES_TEXT_INTENT, item);
    
public static android.content.ClipDatanewPlainText(java.lang.CharSequence label, java.lang.CharSequence text)
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.

        Item item = new Item(text);
        return new ClipData(label, MIMETYPES_TEXT_PLAIN, item);
    
public static android.content.ClipDatanewRawUri(java.lang.CharSequence label, android.net.Uri uri)
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.

        Item item = new Item(uri);
        return new ClipData(label, MIMETYPES_TEXT_URILIST, item);
    
public static android.content.ClipDatanewUri(ContentResolver resolver, java.lang.CharSequence label, android.net.Uri uri)
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.

        Item item = new Item(uri);
        String[] mimeTypes = null;
        if ("content".equals(uri.getScheme())) {
            String realType = resolver.getType(uri);
            mimeTypes = resolver.getStreamTypes(uri, "*/*");
            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);
    
public voidprepareToLeaveProcess()
Prepare this {@link ClipData} to leave an app process.

hide

        final int size = mItems.size();
        for (int i = 0; i < size; i++) {
            final Item item = mItems.get(i);
            if (item.mIntent != null) {
                item.mIntent.prepareToLeaveProcess();
            }
            if (item.mUri != null && StrictMode.vmFileUriExposureEnabled()) {
                item.mUri.checkFileUriExposed("ClipData.Item.getUri()");
            }
        }
    
public voidtoShortString(java.lang.StringBuilder b)

hide

        boolean first;
        if (mClipDescription != null) {
            first = !mClipDescription.toShortString(b);
        } else {
            first = true;
        }
        if (mIcon != null) {
            if (!first) {
                b.append(' ");
            }
            first = false;
            b.append("I:");
            b.append(mIcon.getWidth());
            b.append('x");
            b.append(mIcon.getHeight());
        }
        for (int i=0; i<mItems.size(); i++) {
            if (!first) {
                b.append(' ");
            }
            first = false;
            b.append('{");
            mItems.get(i).toShortString(b);
            b.append('}");
        }
    
public java.lang.StringtoString()

        StringBuilder b = new StringBuilder(128);

        b.append("ClipData { ");
        toShortString(b);
        b.append(" }");

        return b.toString();
    
public voidwriteToParcel(android.os.Parcel dest, int flags)

        mClipDescription.writeToParcel(dest, flags);
        if (mIcon != null) {
            dest.writeInt(1);
            mIcon.writeToParcel(dest, flags);
        } else {
            dest.writeInt(0);
        }
        final int N = mItems.size();
        dest.writeInt(N);
        for (int i=0; i<N; i++) {
            Item item = mItems.get(i);
            TextUtils.writeToParcel(item.mText, dest, flags);
            dest.writeString(item.mHtmlText);
            if (item.mIntent != null) {
                dest.writeInt(1);
                item.mIntent.writeToParcel(dest, flags);
            } else {
                dest.writeInt(0);
            }
            if (item.mUri != null) {
                dest.writeInt(1);
                item.mUri.writeToParcel(dest, flags);
            } else {
                dest.writeInt(0);
            }
        }