19f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn/** 29f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Copyright (c) 2010, The Android Open Source Project 39f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 49f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 59f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * you may not use this file except in compliance with the License. 69f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * You may obtain a copy of the License at 79f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 89f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 99f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 109f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Unless required by applicable law or agreed to in writing, software 119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * See the License for the specific language governing permissions and 149f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * limitations under the License. 159f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 169f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 179f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornpackage android.content; 189f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 1923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport android.content.res.AssetFileDescriptor; 209f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.graphics.Bitmap; 219f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.net.Uri; 229f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.Parcel; 239f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.Parcelable; 24acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.Html; 25acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.Spannable; 26acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.SpannableStringBuilder; 27acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.Spanned; 289f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.text.TextUtils; 29acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.style.URLSpan; 3023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport android.util.Log; 319f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 3223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.FileInputStream; 3323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.FileNotFoundException; 3423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.IOException; 3523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.InputStreamReader; 369f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport java.util.ArrayList; 379f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 389f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn/** 399f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Representation of a clipped data on the clipboard. 409f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 419f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * <p>ClippedData is a complex type containing one or Item instances, 429f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * each of which can hold one or more representations of an item of data. 439f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * For display to the user, it also has a label and iconic representation.</p> 449f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 45f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * <p>A ClipData contains a {@link ClipDescription}, which describes 46f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * important meta-data about the clip. In particular, its 47f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#getMimeType(int) getDescription().getMimeType(int)} 481040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * must return correct MIME type(s) describing the data in the clip. For help 491040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * in correctly constructing a clip with the correct MIME type, use 50327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * {@link #newPlainText(CharSequence, CharSequence)}, 51327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * {@link #newUri(ContentResolver, CharSequence, Uri)}, and 52327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * {@link #newIntent(CharSequence, Intent)}. 531040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 5423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Each Item instance can be one of three main classes of data: a simple 5523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * CharSequence of text, a single Intent object, or a Uri. See {@link Item} 5623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * for more details. 5723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 583aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference"> 593aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3> 603aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about using the clipboard framework, read the 613aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/clipboard/copy-paste.html">Copy and Paste</a> 623aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * developer guide.</p> 633aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div> 643aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * 6523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <a name="ImplementingPaste"></a> 6623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <h3>Implementing Paste or Drop</h3> 6723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 6823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>To implement a paste or drop of a ClippedData object into an application, 6923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the application must correctly interpret the data for its use. If the {@link Item} 7023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it contains is simple text or an Intent, there is little to be done: text 7123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * can only be interpreted as text, and an Intent will typically be used for 7223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * creating shortcuts (such as placing icons on the home screen) or other 7323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * actions. 7423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 7523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>If all you want is the textual representation of the clipped data, you 7623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * can use the convenience method {@link Item#coerceToText Item.coerceToText}. 771040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * In this case there is generally no need to worry about the MIME types 78f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * reported by {@link ClipDescription#getMimeType(int) getDescription().getMimeType(int)}, 79f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * since any clip item an always be converted to a string. 8023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 8123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>More complicated exchanges will be done through URIs, in particular 8223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * "content:" URIs. A content URI allows the recipient of a ClippedData item 8323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * to interact closely with the ContentProvider holding the data in order to 841040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * negotiate the transfer of that data. The clip must also be filled in with 85327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * the available MIME types; {@link #newUri(ContentResolver, CharSequence, Uri)} 861040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * will take care of correctly doing this. 8723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 8823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>For example, here is the paste function of a simple NotePad application. 8923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * When retrieving the data from the clipboard, it can do either two things: 9023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * if the clipboard contains a URI reference to an existing note, it copies 9123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the entire structure of the note into a new note; otherwise, it simply 9223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * coerces the clip into text and uses that as the new note's contents. 9323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 9423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@sample development/samples/NotePad/src/com/example/android/notepad/NoteEditor.java 9523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * paste} 9623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 9723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>In many cases an application can paste various types of streams of data. For 9823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * example, an e-mail application may want to allow the user to paste an image 9923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * or other binary data as an attachment. This is accomplished through the 10023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * ContentResolver {@link ContentResolver#getStreamTypes(Uri, String)} and 10123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, android.os.Bundle)} 10223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * methods. These allow a client to discover the type(s) of data that a particular 10323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content URI can make available as a stream and retrieve the stream of data. 10423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 10523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>For example, the implementation of {@link Item#coerceToText Item.coerceToText} 10623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * itself uses this to try to retrieve a URI clip as a stream of text: 10723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 108f6d952bbc85706031e1ad29ec389c1e02cfff433Dianne Hackborn * {@sample frameworks/base/core/java/android/content/ClipData.java coerceToText} 10923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 11023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <a name="ImplementingCopy"></a> 11123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <h3>Implementing Copy or Drag</h3> 11223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 11323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>To be the source of a clip, the application must construct a ClippedData 11423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * object that any recipient can interpret best for their context. If the clip 11523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * is to contain a simple text, Intent, or URI, this is easy: an {@link Item} 11623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * containing the appropriate data type can be constructed and used. 11723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 11823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>More complicated data types require the implementation of support in 11923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * a ContentProvider for describing and generating the data for the recipient. 12023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * A common scenario is one where an application places on the clipboard the 12123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content: URI of an object that the user has copied, with the data at that 12223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * URI consisting of a complicated structure that only other applications with 12323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * direct knowledge of the structure can use. 12423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 12523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>For applications that do not have intrinsic knowledge of the data structure, 12623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the content provider holding it can make the data available as an arbitrary 12723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * number of types of data streams. This is done by implementing the 12823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * ContentProvider {@link ContentProvider#getStreamTypes(Uri, String)} and 12923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentProvider#openTypedAssetFile(Uri, String, android.os.Bundle)} 13023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * methods. 13123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 13223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Going back to our simple NotePad application, this is the implementation 13323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it may have to convert a single note URI (consisting of a title and the note 13423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * text) into a stream of plain text data. 13523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 13623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@sample development/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java 13723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * stream} 13823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 13923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>The copy operation in our NotePad application is now just a simple matter 14023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * of making a clip containing the URI of the note being copied: 14123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 14223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@sample development/samples/NotePad/src/com/example/android/notepad/NotesList.java 14323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * copy} 14423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 14523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Note if a paste operation needs this clip as text (for example to paste 14623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * into an editor), then {@link Item#coerceToText(Context)} will ask the content 14723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * provider for the clip URI as text and successfully paste the entire note. 1489f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 149f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackbornpublic class ClipData implements Parcelable { 150f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn static final String[] MIMETYPES_TEXT_PLAIN = new String[] { 151f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn ClipDescription.MIMETYPE_TEXT_PLAIN }; 152acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn static final String[] MIMETYPES_TEXT_HTML = new String[] { 153acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn ClipDescription.MIMETYPE_TEXT_HTML }; 154f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn static final String[] MIMETYPES_TEXT_URILIST = new String[] { 155f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn ClipDescription.MIMETYPE_TEXT_URILIST }; 156f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn static final String[] MIMETYPES_TEXT_INTENT = new String[] { 157f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn ClipDescription.MIMETYPE_TEXT_INTENT }; 158f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn 159f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn final ClipDescription mClipDescription; 160f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn 1611040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn final Bitmap mIcon; 1629f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 16321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn final ArrayList<Item> mItems; 1649f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 16523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 16623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Description of a single item in a ClippedData. 16723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 16823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>The types than an individual item can currently contain are:</p> 16923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 17023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <ul> 17123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> Text: a basic string of text. This is actually a CharSequence, 17223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * so it can be formatted text supported by corresponding Android built-in 17323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * style spans. (Custom application spans are not supported and will be 17423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * stripped when transporting through the clipboard.) 17523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> Intent: an arbitrary Intent object. A typical use is the shortcut 17623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * to create when pasting a clipped item on to the home screen. 17723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> Uri: a URI reference. This may be any URI (such as an http: URI 17823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * representing a bookmark), however it is often a content: URI. Using 17923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content provider references as clips like this allows an application to 18023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * share complex or large clips through the standard content provider 18123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * facilities. 18223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * </ul> 18323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 1849f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public static class Item { 1851040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn final CharSequence mText; 186acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn final String mHtmlText; 1871040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn final Intent mIntent; 1881040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn final Uri mUri; 1899f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 19023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 19123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Create an Item consisting of a single block of (possibly styled) text. 19223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 1939f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Item(CharSequence text) { 1949f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mText = text; 195acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = null; 196acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mIntent = null; 197acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mUri = null; 198acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 199acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 200acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 201acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Create an Item consisting of a single block of (possibly styled) text, 202acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * with an alternative HTML formatted representation. You <em>must</em> 203acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * supply a plain text representation in addition to HTML text; coercion 204acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * will not be done from HTML formated text into plain text. 205acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 206acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public Item(CharSequence text, String htmlText) { 207acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mText = text; 208acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = htmlText; 2091040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mIntent = null; 2101040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mUri = null; 2119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 21323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 21423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Create an Item consisting of an arbitrary Intent. 21523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2169f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Item(Intent intent) { 2171040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mText = null; 218acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = null; 2199f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mIntent = intent; 2201040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mUri = null; 2219f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2229f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 22323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 22423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Create an Item consisting of an arbitrary URI. 22523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2269f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Item(Uri uri) { 2271040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mText = null; 228acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = null; 2291040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mIntent = null; 2309f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mUri = uri; 2319f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2329f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 23323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 23423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Create a complex Item, containing multiple representations of 235acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * text, Intent, and/or URI. 23623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2379f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Item(CharSequence text, Intent intent, Uri uri) { 2389f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mText = text; 239acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = null; 240acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mIntent = intent; 241acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mUri = uri; 242acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 243acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 244acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 245acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Create a complex Item, containing multiple representations of 246acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * text, HTML text, Intent, and/or URI. If providing HTML text, you 247acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <em>must</em> supply a plain text representation as well; coercion 248acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * will not be done from HTML formated text into plain text. 249acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 250acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public Item(CharSequence text, String htmlText, Intent intent, Uri uri) { 251acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (htmlText != null && text == null) { 252acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn throw new IllegalArgumentException( 253acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn "Plain text must be supplied if HTML text is supplied"); 254acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 255acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mText = text; 256acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = htmlText; 2579f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mIntent = intent; 2589f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mUri = uri; 2599f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2609f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 26123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 26223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Retrieve the raw text contained in this Item. 26323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2649f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public CharSequence getText() { 2659f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mText; 2669f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2679f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 26823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 269acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Retrieve the raw HTML text contained in this Item. 270acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 271acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public String getHtmlText() { 272acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return mHtmlText; 273acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 274acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 275acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 27623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Retrieve the raw Intent contained in this Item. 27723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2789f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Intent getIntent() { 2799f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mIntent; 2809f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2819f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 28223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 28323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Retrieve the raw URI contained in this Item. 28423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2859f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Uri getUri() { 2869f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mUri; 2879f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 28823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 28923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 29023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Turn this item into text, regardless of the type of data it 29123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * actually contains. 29223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 29323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>The algorithm for deciding what text to return is: 29423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <ul> 29523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> If {@link #getText} is non-null, return that. 29623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> If {@link #getUri} is non-null, try to retrieve its data 29723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * as a text stream from its content provider. If this succeeds, copy 29823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the text into a String and return it. If it is not a content: URI or 29923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the content provider does not supply a text representation, return 30023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the raw URI as a string. 30123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> If {@link #getIntent} is non-null, convert that to an intent: 302acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * URI and return it. 30323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> Otherwise, return an empty string. 30423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * </ul> 30523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 30623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param context The caller's Context, from which its ContentResolver 30723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * and other things can be retrieved. 30823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @return Returns the item's textual representation. 30923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 31023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn//BEGIN_INCLUDE(coerceToText) 31123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public CharSequence coerceToText(Context context) { 31223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // If this Item has an explicit textual value, simply return that. 313acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence text = getText(); 314acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text != null) { 315acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 31623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 31723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 31823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // If this Item has a URI value, try using that. 319acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Uri uri = getUri(); 320acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (uri != null) { 32123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 32223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // First see if the URI can be opened as a plain text stream 32323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // (of any sub-type). If so, this is the best textual 32423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // representation for it. 32523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn FileInputStream stream = null; 32623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 32723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Ask for a stream of the desired type. 32823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn AssetFileDescriptor descr = context.getContentResolver() 329acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn .openTypedAssetFileDescriptor(uri, "text/*", null); 33023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn stream = descr.createInputStream(); 33123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn InputStreamReader reader = new InputStreamReader(stream, "UTF-8"); 33223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 33323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Got it... copy the stream into a local string and return it. 33423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn StringBuilder builder = new StringBuilder(128); 33523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn char[] buffer = new char[8192]; 33623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn int len; 33723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn while ((len=reader.read(buffer)) > 0) { 33823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn builder.append(buffer, 0, len); 33923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 34023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return builder.toString(); 34123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 34223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (FileNotFoundException e) { 34323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Unable to open content URI as text... not really an 34423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // error, just something to ignore. 34523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 34623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (IOException e) { 34723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Something bad has happened. 34823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn Log.w("ClippedData", "Failure loading text", e); 34923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return e.toString(); 35023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 35123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } finally { 35223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if (stream != null) { 35323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 35423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn stream.close(); 35523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (IOException e) { 35623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 35723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 35823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 35923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 36023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // If we couldn't open the URI as a stream, then the URI itself 36123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // probably serves fairly well as a textual representation. 362acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uri.toString(); 36323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 36423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 36523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Finally, if all we have is an Intent, then we can just turn that 36623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // into text. Not the most user-friendly thing, but it's something. 367acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Intent intent = getIntent(); 368acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (intent != null) { 369acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return intent.toUri(Intent.URI_INTENT_SCHEME); 37023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 37123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 37223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Shouldn't get here, but just in case... 37323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return ""; 37423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 37523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn//END_INCLUDE(coerceToText) 37621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 377acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 378acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Like {@link #coerceToHtmlText(Context)}, but any text that would 379acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * be returned as HTML formatting will be returned as text with 380acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * style spans. 381acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param context The caller's Context, from which its ContentResolver 382acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * and other things can be retrieved. 383acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns the item's textual representation. 384acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 385acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public CharSequence coerceToStyledText(Context context) { 386acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence text = getText(); 387acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text instanceof Spanned) { 388acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 389acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 390acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String htmlText = getHtmlText(); 391acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (htmlText != null) { 392acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn try { 393acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence newText = Html.fromHtml(htmlText); 394acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (newText != null) { 395acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return newText; 396acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 397acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (RuntimeException e) { 398acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If anything bad happens, we'll fall back on the plain text. 399acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 400acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 401acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 402acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text != null) { 403acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 404acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 405acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return coerceToHtmlOrStyledText(context, true); 406acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 407acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 408acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 409acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Turn this item into HTML text, regardless of the type of data it 410acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * actually contains. 411acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * 412acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <p>The algorithm for deciding what text to return is: 413acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <ul> 414acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> If {@link #getHtmlText} is non-null, return that. 415acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> If {@link #getText} is non-null, return that, converting to 416acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * valid HTML text. If this text contains style spans, 417acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * {@link Html#toHtml(Spanned) Html.toHtml(Spanned)} is used to 418acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * convert them to HTML formatting. 419acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> If {@link #getUri} is non-null, try to retrieve its data 420acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * as a text stream from its content provider. If the provider can 421acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * supply text/html data, that will be preferred and returned as-is. 422acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Otherwise, any text/* data will be returned and escaped to HTML. 423acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * If it is not a content: URI or the content provider does not supply 424acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * a text representation, HTML text containing a link to the URI 425acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * will be returned. 426acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> If {@link #getIntent} is non-null, convert that to an intent: 427acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * URI and return as an HTML link. 428acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> Otherwise, return an empty string. 429acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * </ul> 430acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * 431acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param context The caller's Context, from which its ContentResolver 432acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * and other things can be retrieved. 433acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns the item's representation as HTML text. 434acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 435acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public String coerceToHtmlText(Context context) { 436acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If the item has an explicit HTML value, simply return that. 437acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String htmlText = getHtmlText(); 438acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (htmlText != null) { 439acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return htmlText; 440acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 441acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 442acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If this Item has a plain text value, return it as HTML. 443acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence text = getText(); 444acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text != null) { 445acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text instanceof Spanned) { 446acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return Html.toHtml((Spanned)text); 447acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 448acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return Html.escapeHtml(text); 449acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 450acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 451acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn text = coerceToHtmlOrStyledText(context, false); 452acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text != null ? text.toString() : null; 453acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 454acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 455acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn private CharSequence coerceToHtmlOrStyledText(Context context, boolean styled) { 456acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If this Item has a URI value, try using that. 457acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (mUri != null) { 458acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 459acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Check to see what data representations the content 460acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // provider supports. We would like HTML text, but if that 461acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // is not possible we'll live with plan text. 462acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String[] types = context.getContentResolver().getStreamTypes(mUri, "text/*"); 463acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn boolean hasHtml = false; 464acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn boolean hasText = false; 465acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (types != null) { 466acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn for (String type : types) { 467acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if ("text/html".equals(type)) { 468acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn hasHtml = true; 469acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else if (type.startsWith("text/")) { 470acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn hasText = true; 471acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 472acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 473acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 474acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 475acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If the provider can serve data we can use, open and load it. 476acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (hasHtml || hasText) { 477acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn FileInputStream stream = null; 478acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn try { 479acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Ask for a stream of the desired type. 480acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn AssetFileDescriptor descr = context.getContentResolver() 481acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn .openTypedAssetFileDescriptor(mUri, 482acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn hasHtml ? "text/html" : "text/plain", null); 483acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn stream = descr.createInputStream(); 484acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn InputStreamReader reader = new InputStreamReader(stream, "UTF-8"); 485acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 486acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Got it... copy the stream into a local string and return it. 487acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn StringBuilder builder = new StringBuilder(128); 488acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn char[] buffer = new char[8192]; 489acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn int len; 490acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn while ((len=reader.read(buffer)) > 0) { 491acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append(buffer, 0, len); 492acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 493acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String text = builder.toString(); 494acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (hasHtml) { 495acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (styled) { 496acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // We loaded HTML formatted text and the caller 497acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // want styled text, convert it. 498acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn try { 499acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence newText = Html.fromHtml(text); 500acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return newText != null ? newText : text; 501acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (RuntimeException e) { 502acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 503acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 504acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else { 505acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // We loaded HTML formatted text and that is what 506acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // the caller wants, just return it. 507acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text.toString(); 508acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 509acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 510acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (styled) { 511acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // We loaded plain text and the caller wants styled 512acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // text, that is all we have so return it. 513acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 514acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else { 515acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // We loaded plain text and the caller wants HTML 516acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // text, escape it for HTML. 517acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return Html.escapeHtml(text); 518acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 519acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 520acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (FileNotFoundException e) { 521acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Unable to open content URI as text... not really an 522acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // error, just something to ignore. 523acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 524acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (IOException e) { 525acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Something bad has happened. 526acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Log.w("ClippedData", "Failure loading text", e); 527acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return Html.escapeHtml(e.toString()); 528acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 529acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } finally { 530acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (stream != null) { 531acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn try { 532acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn stream.close(); 533acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (IOException e) { 534acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 535acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 536acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 537acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 538acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 539acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If we couldn't open the URI as a stream, then we can build 540acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // some HTML text with the URI itself. 541acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // probably serves fairly well as a textual representation. 542acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (styled) { 543acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uriToStyledText(mUri.toString()); 544acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else { 545acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uriToHtml(mUri.toString()); 546acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 547acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 548acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 549acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Finally, if all we have is an Intent, then we can just turn that 550acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // into text. Not the most user-friendly thing, but it's something. 551acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (mIntent != null) { 552acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (styled) { 553acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uriToStyledText(mIntent.toUri(Intent.URI_INTENT_SCHEME)); 554acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else { 555acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uriToHtml(mIntent.toUri(Intent.URI_INTENT_SCHEME)); 556acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 557acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 558acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 559acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Shouldn't get here, but just in case... 560acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return ""; 561acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 562acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 563acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn private String uriToHtml(String uri) { 564acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn StringBuilder builder = new StringBuilder(256); 565acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append("<a href=\""); 566acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append(uri); 567acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append("\">"); 568acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append(Html.escapeHtml(uri)); 569acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append("</a>"); 570acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return builder.toString(); 571acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 572acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 573acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn private CharSequence uriToStyledText(String uri) { 574acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn SpannableStringBuilder builder = new SpannableStringBuilder(); 575acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append(uri); 576acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.setSpan(new URLSpan(uri), 0, builder.length(), 577acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 578acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return builder; 579acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 580acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 58121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn @Override 58221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public String toString() { 58321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn StringBuilder b = new StringBuilder(128); 58421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 58521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("ClipData.Item { "); 58621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn toShortString(b); 58721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(" }"); 58821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 58921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn return b.toString(); 59021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 59121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 59221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn /** @hide */ 59321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public void toShortString(StringBuilder b) { 594acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (mHtmlText != null) { 595acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn b.append("H:"); 596acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn b.append(mHtmlText); 597acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else if (mText != null) { 59821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("T:"); 59921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(mText); 60021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } else if (mUri != null) { 60121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("U:"); 60221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(mUri); 60321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } else if (mIntent != null) { 60421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("I:"); 60521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mIntent.toShortString(b, true, true, true, true); 60621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } else { 60721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("NULL"); 60821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 60921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 6109f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 6119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 6129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** 6139f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Create a new clip. 6149f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 6159f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * @param label Label to show to the user describing this clip. 6161040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param mimeTypes An array of MIME types this data is available as. 6179f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * @param item The contents of the first item in the clip. 6189f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 619327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public ClipData(CharSequence label, String[] mimeTypes, Item item) { 620f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mClipDescription = new ClipDescription(label, mimeTypes); 621f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn if (item == null) { 622f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn throw new NullPointerException("item is null"); 623f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn } 624327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn mIcon = null; 62521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems = new ArrayList<Item>(); 626f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mItems.add(item); 627f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn } 628f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn 629f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn /** 630f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Create a new clip. 631f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * 632f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * @param description The ClipDescription describing the clip contents. 633f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * @param item The contents of the first item in the clip. 634f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn */ 635327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public ClipData(ClipDescription description, Item item) { 636f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mClipDescription = description; 6379f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (item == null) { 6389f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn throw new NullPointerException("item is null"); 6399f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 640327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn mIcon = null; 64121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems = new ArrayList<Item>(); 6429f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mItems.add(item); 6439f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 6449f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 6451040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 64621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn * Create a new clip that is a copy of another clip. This does a deep-copy 64721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn * of all items in the clip. 64821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn * 64921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn * @param other The existing ClipData that is to be copied. 65021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn */ 65121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public ClipData(ClipData other) { 65221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mClipDescription = other.mClipDescription; 65321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mIcon = other.mIcon; 65421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems = new ArrayList<Item>(other.mItems); 65521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 65621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 65721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn /** 658f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Create a new ClipData holding data of the type 659f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_PLAIN}. 6601040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 6611040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param label User-visible label for the clip data. 6621040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param text The actual text in the clip. 6631040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @return Returns a new ClipData containing the specified data. 6641040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 665327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn static public ClipData newPlainText(CharSequence label, CharSequence text) { 6661040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn Item item = new Item(text); 667327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return new ClipData(label, MIMETYPES_TEXT_PLAIN, item); 668327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn } 669327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn 6701040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 671acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Create a new ClipData holding data of the type 672acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_HTML}. 673acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * 674acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param label User-visible label for the clip data. 675acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param text The text of clip as plain text, for receivers that don't 676acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * handle HTML. This is required. 677acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param htmlText The actual HTML text in the clip. 678acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns a new ClipData containing the specified data. 679acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 680acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn static public ClipData newHtmlText(CharSequence label, CharSequence text, 681acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String htmlText) { 682acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Item item = new Item(text, htmlText); 683acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return new ClipData(label, MIMETYPES_TEXT_HTML, item); 684acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 685acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 686acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 687f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Create a new ClipData holding an Intent with MIME type 688f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_INTENT}. 6891040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 6901040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param label User-visible label for the clip data. 6911040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param intent The actual Intent in the clip. 6921040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @return Returns a new ClipData containing the specified data. 6931040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 694327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn static public ClipData newIntent(CharSequence label, Intent intent) { 6951040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn Item item = new Item(intent); 696327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return new ClipData(label, MIMETYPES_TEXT_INTENT, item); 6971040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 6981040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn 6991040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 7001040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * Create a new ClipData holding a URI. If the URI is a content: URI, 7011040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * this will query the content provider for the MIME type of its data and 7021040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * use that as the MIME type. Otherwise, it will use the MIME type 703f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_URILIST}. 7041040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 7051040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param resolver ContentResolver used to get information about the URI. 7061040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param label User-visible label for the clip data. 7071040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param uri The URI in the clip. 7081040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @return Returns a new ClipData containing the specified data. 7091040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 7101040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn static public ClipData newUri(ContentResolver resolver, CharSequence label, 711327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn Uri uri) { 7121040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn Item item = new Item(uri); 7131040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn String[] mimeTypes = null; 7141040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if ("content".equals(uri.getScheme())) { 7151040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn String realType = resolver.getType(uri); 7161040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mimeTypes = resolver.getStreamTypes(uri, "*/*"); 7171040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if (mimeTypes == null) { 7181040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if (realType != null) { 719f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mimeTypes = new String[] { realType, ClipDescription.MIMETYPE_TEXT_URILIST }; 7201040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7211040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } else { 7221040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn String[] tmp = new String[mimeTypes.length + (realType != null ? 2 : 1)]; 7231040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn int i = 0; 7241040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if (realType != null) { 7251040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn tmp[0] = realType; 7261040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn i++; 7271040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7281040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn System.arraycopy(mimeTypes, 0, tmp, i, mimeTypes.length); 729f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn tmp[i + mimeTypes.length] = ClipDescription.MIMETYPE_TEXT_URILIST; 7301040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mimeTypes = tmp; 7311040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7321040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7331040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if (mimeTypes == null) { 7341040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mimeTypes = MIMETYPES_TEXT_URILIST; 7351040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 736327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return new ClipData(label, mimeTypes, item); 7371040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7381040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn 7391040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 740f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Create a new ClipData holding an URI with MIME type 741f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_URILIST}. 742327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * Unlike {@link #newUri(ContentResolver, CharSequence, Uri)}, nothing 7431040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * is inferred about the URI -- if it is a content: URI holding a bitmap, 7441040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * the reported type will still be uri-list. Use this with care! 7451040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 7461040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param label User-visible label for the clip data. 7471040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param uri The URI in the clip. 7481040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @return Returns a new ClipData containing the specified data. 7491040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 750327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn static public ClipData newRawUri(CharSequence label, Uri uri) { 7511040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn Item item = new Item(uri); 752327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return new ClipData(label, MIMETYPES_TEXT_URILIST, item); 7531040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7541040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn 755f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn /** 756f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Return the {@link ClipDescription} associated with this data, describing 757f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * what it contains. 758f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn */ 759f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn public ClipDescription getDescription() { 760f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn return mClipDescription; 761f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn } 762f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn 763327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn /** 764327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * Add a new Item to the overall ClipData container. 765327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn */ 7669f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void addItem(Item item) { 7679f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (item == null) { 7689f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn throw new NullPointerException("item is null"); 7699f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7709f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mItems.add(item); 7719f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7729f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 773327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn /** @hide */ 7749f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Bitmap getIcon() { 7759f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mIcon; 7769f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7779f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 778327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn /** 779327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * Return the number of items in the clip data. 780327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn */ 7819f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public int getItemCount() { 7829f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mItems.size(); 7839f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7849f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 785327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn /** 786327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * Return a single item inside of the clip data. The index can range 787327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * from 0 to {@link #getItemCount()}-1. 788327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn */ 789327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public Item getItemAt(int index) { 7909f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mItems.get(index); 7919f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7929f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 7939f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn @Override 79421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public String toString() { 79521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn StringBuilder b = new StringBuilder(128); 79621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 79721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("ClipData { "); 79821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn toShortString(b); 79921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(" }"); 80021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 80121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn return b.toString(); 80221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 80321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 80421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn /** @hide */ 80521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public void toShortString(StringBuilder b) { 80621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn boolean first; 80721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn if (mClipDescription != null) { 80821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn first = !mClipDescription.toShortString(b); 80921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } else { 81021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn first = true; 81121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 81221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn if (mIcon != null) { 81321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn if (!first) { 81421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(' '); 81521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 81621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn first = false; 81721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("I:"); 81821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(mIcon.getWidth()); 81921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append('x'); 82021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(mIcon.getHeight()); 82121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 82221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn for (int i=0; i<mItems.size(); i++) { 82321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn if (!first) { 82421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(' '); 82521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 82621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn first = false; 82721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append('{'); 82821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems.get(i).toShortString(b); 82921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append('}'); 83021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 83121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 83221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 83321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn @Override 8349f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public int describeContents() { 8359f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return 0; 8369f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8379f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 8389f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn @Override 8399f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void writeToParcel(Parcel dest, int flags) { 840f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mClipDescription.writeToParcel(dest, flags); 8419f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (mIcon != null) { 8429f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(1); 8439f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mIcon.writeToParcel(dest, flags); 8449f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } else { 8459f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(0); 8469f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8479f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn final int N = mItems.size(); 8489f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(N); 8499f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn for (int i=0; i<N; i++) { 8509f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn Item item = mItems.get(i); 8519f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn TextUtils.writeToParcel(item.mText, dest, flags); 852acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn dest.writeString(item.mHtmlText); 8539f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (item.mIntent != null) { 8549f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(1); 8559f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn item.mIntent.writeToParcel(dest, flags); 8569f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } else { 8579f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(0); 8589f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8599f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (item.mUri != null) { 8609f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(1); 8619f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn item.mUri.writeToParcel(dest, flags); 8629f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } else { 8639f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(0); 8649f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8659f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8669f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8679f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 8681040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn ClipData(Parcel in) { 869f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mClipDescription = new ClipDescription(in); 8709f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (in.readInt() != 0) { 8719f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mIcon = Bitmap.CREATOR.createFromParcel(in); 8721040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } else { 8731040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mIcon = null; 8749f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 87521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems = new ArrayList<Item>(); 8769f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn final int N = in.readInt(); 8779f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn for (int i=0; i<N; i++) { 8789f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 879acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String htmlText = in.readString(); 8809f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn Intent intent = in.readInt() != 0 ? Intent.CREATOR.createFromParcel(in) : null; 8819f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn Uri uri = in.readInt() != 0 ? Uri.CREATOR.createFromParcel(in) : null; 882acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mItems.add(new Item(text, htmlText, intent, uri)); 8839f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8849f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8859f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 8861040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public static final Parcelable.Creator<ClipData> CREATOR = 8871040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn new Parcelable.Creator<ClipData>() { 8889f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 8891040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public ClipData createFromParcel(Parcel source) { 8901040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn return new ClipData(source); 8919f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8929f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 8931040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public ClipData[] newArray(int size) { 8941040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn return new ClipData[size]; 8959f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8969f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn }; 8979f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn} 898