ClipData.java revision a14acd20b8d563319ea1a5974dca0e9a29f0aaef
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; 24a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkeyimport android.os.StrictMode; 25acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.Html; 26acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.Spannable; 27acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.SpannableStringBuilder; 28acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.Spanned; 299f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.text.TextUtils; 30acb69bb909d098cea284df47d794c17171d84c91Dianne Hackbornimport android.text.style.URLSpan; 3123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport android.util.Log; 329f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 3323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.FileInputStream; 3423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.FileNotFoundException; 3523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.IOException; 3623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackbornimport java.io.InputStreamReader; 379f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport java.util.ArrayList; 389f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 399f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn/** 409f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Representation of a clipped data on the clipboard. 419f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 429f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * <p>ClippedData is a complex type containing one or Item instances, 439f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * each of which can hold one or more representations of an item of data. 449f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * For display to the user, it also has a label and iconic representation.</p> 459f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 46f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * <p>A ClipData contains a {@link ClipDescription}, which describes 47f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * important meta-data about the clip. In particular, its 48f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#getMimeType(int) getDescription().getMimeType(int)} 491040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * must return correct MIME type(s) describing the data in the clip. For help 501040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * in correctly constructing a clip with the correct MIME type, use 51327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * {@link #newPlainText(CharSequence, CharSequence)}, 52327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * {@link #newUri(ContentResolver, CharSequence, Uri)}, and 53327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * {@link #newIntent(CharSequence, Intent)}. 541040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 5523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Each Item instance can be one of three main classes of data: a simple 5623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * CharSequence of text, a single Intent object, or a Uri. See {@link Item} 5723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * for more details. 5823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 593aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference"> 603aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3> 613aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about using the clipboard framework, read the 623aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/clipboard/copy-paste.html">Copy and Paste</a> 633aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * developer guide.</p> 643aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div> 653aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * 6623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <a name="ImplementingPaste"></a> 6723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <h3>Implementing Paste or Drop</h3> 6823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 6923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>To implement a paste or drop of a ClippedData object into an application, 7023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the application must correctly interpret the data for its use. If the {@link Item} 7123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it contains is simple text or an Intent, there is little to be done: text 7223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * can only be interpreted as text, and an Intent will typically be used for 7323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * creating shortcuts (such as placing icons on the home screen) or other 7423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * actions. 7523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 7623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>If all you want is the textual representation of the clipped data, you 7723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * can use the convenience method {@link Item#coerceToText Item.coerceToText}. 781040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * In this case there is generally no need to worry about the MIME types 79f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * reported by {@link ClipDescription#getMimeType(int) getDescription().getMimeType(int)}, 80f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * since any clip item an always be converted to a string. 8123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 8223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>More complicated exchanges will be done through URIs, in particular 8323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * "content:" URIs. A content URI allows the recipient of a ClippedData item 8423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * to interact closely with the ContentProvider holding the data in order to 851040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * negotiate the transfer of that data. The clip must also be filled in with 86327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * the available MIME types; {@link #newUri(ContentResolver, CharSequence, Uri)} 871040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * will take care of correctly doing this. 8823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 8923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>For example, here is the paste function of a simple NotePad application. 9023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * When retrieving the data from the clipboard, it can do either two things: 9123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * if the clipboard contains a URI reference to an existing note, it copies 9223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the entire structure of the note into a new note; otherwise, it simply 9323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * coerces the clip into text and uses that as the new note's contents. 9423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 9523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@sample development/samples/NotePad/src/com/example/android/notepad/NoteEditor.java 9623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * paste} 9723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 9823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>In many cases an application can paste various types of streams of data. For 9923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * example, an e-mail application may want to allow the user to paste an image 10023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * or other binary data as an attachment. This is accomplished through the 10123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * ContentResolver {@link ContentResolver#getStreamTypes(Uri, String)} and 10223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, android.os.Bundle)} 10323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * methods. These allow a client to discover the type(s) of data that a particular 10423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content URI can make available as a stream and retrieve the stream of data. 10523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 10623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>For example, the implementation of {@link Item#coerceToText Item.coerceToText} 10723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * itself uses this to try to retrieve a URI clip as a stream of text: 10823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 109f6d952bbc85706031e1ad29ec389c1e02cfff433Dianne Hackborn * {@sample frameworks/base/core/java/android/content/ClipData.java coerceToText} 11023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 11123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <a name="ImplementingCopy"></a> 11223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <h3>Implementing Copy or Drag</h3> 11323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 11423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>To be the source of a clip, the application must construct a ClippedData 11523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * object that any recipient can interpret best for their context. If the clip 11623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * is to contain a simple text, Intent, or URI, this is easy: an {@link Item} 11723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * containing the appropriate data type can be constructed and used. 11823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 11923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>More complicated data types require the implementation of support in 12023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * a ContentProvider for describing and generating the data for the recipient. 12123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * A common scenario is one where an application places on the clipboard the 12223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content: URI of an object that the user has copied, with the data at that 12323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * URI consisting of a complicated structure that only other applications with 12423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * direct knowledge of the structure can use. 12523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 12623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>For applications that do not have intrinsic knowledge of the data structure, 12723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the content provider holding it can make the data available as an arbitrary 12823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * number of types of data streams. This is done by implementing the 12923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * ContentProvider {@link ContentProvider#getStreamTypes(Uri, String)} and 13023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@link ContentProvider#openTypedAssetFile(Uri, String, android.os.Bundle)} 13123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * methods. 13223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 13323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Going back to our simple NotePad application, this is the implementation 13423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * it may have to convert a single note URI (consisting of a title and the note 13523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * text) into a stream of plain text data. 13623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 13723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@sample development/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java 13823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * stream} 13923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 14023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>The copy operation in our NotePad application is now just a simple matter 14123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * of making a clip containing the URI of the note being copied: 14223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 14323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * {@sample development/samples/NotePad/src/com/example/android/notepad/NotesList.java 14423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * copy} 14523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 14623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>Note if a paste operation needs this clip as text (for example to paste 14723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * into an editor), then {@link Item#coerceToText(Context)} will ask the content 14823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * provider for the clip URI as text and successfully paste the entire note. 1499f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 150f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackbornpublic class ClipData implements Parcelable { 151f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn static final String[] MIMETYPES_TEXT_PLAIN = new String[] { 152f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn ClipDescription.MIMETYPE_TEXT_PLAIN }; 153acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn static final String[] MIMETYPES_TEXT_HTML = new String[] { 154acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn ClipDescription.MIMETYPE_TEXT_HTML }; 155f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn static final String[] MIMETYPES_TEXT_URILIST = new String[] { 156f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn ClipDescription.MIMETYPE_TEXT_URILIST }; 157f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn static final String[] MIMETYPES_TEXT_INTENT = new String[] { 158f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn ClipDescription.MIMETYPE_TEXT_INTENT }; 159f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn 160f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn final ClipDescription mClipDescription; 161f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn 1621040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn final Bitmap mIcon; 1639f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 16421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn final ArrayList<Item> mItems; 1659f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 16623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 16723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Description of a single item in a ClippedData. 16823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 16923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>The types than an individual item can currently contain are:</p> 17023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 17123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <ul> 17223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> Text: a basic string of text. This is actually a CharSequence, 17323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * so it can be formatted text supported by corresponding Android built-in 17423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * style spans. (Custom application spans are not supported and will be 17523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * stripped when transporting through the clipboard.) 17623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> Intent: an arbitrary Intent object. A typical use is the shortcut 17723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * to create when pasting a clipped item on to the home screen. 17823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> Uri: a URI reference. This may be any URI (such as an http: URI 17923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * representing a bookmark), however it is often a content: URI. Using 18023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * content provider references as clips like this allows an application to 18123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * share complex or large clips through the standard content provider 18223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * facilities. 18323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * </ul> 18423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 1859f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public static class Item { 1861040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn final CharSequence mText; 187acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn final String mHtmlText; 1881040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn final Intent mIntent; 1891040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn final Uri mUri; 1909f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 19123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 19223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Create an Item consisting of a single block of (possibly styled) text. 19323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 1949f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Item(CharSequence text) { 1959f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mText = text; 196acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = null; 197acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mIntent = null; 198acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mUri = null; 199acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 200acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 201acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 202acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Create an Item consisting of a single block of (possibly styled) text, 203acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * with an alternative HTML formatted representation. You <em>must</em> 204acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * supply a plain text representation in addition to HTML text; coercion 205acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * will not be done from HTML formated text into plain text. 206acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 207acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public Item(CharSequence text, String htmlText) { 208acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mText = text; 209acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = htmlText; 2101040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mIntent = null; 2111040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mUri = null; 2129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2139f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 21423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 21523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Create an Item consisting of an arbitrary Intent. 21623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2179f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Item(Intent intent) { 2181040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mText = null; 219acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = null; 2209f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mIntent = intent; 2211040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mUri = null; 2229f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2239f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 22423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 22523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Create an Item consisting of an arbitrary URI. 22623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2279f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Item(Uri uri) { 2281040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mText = null; 229acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = null; 2301040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mIntent = null; 2319f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mUri = uri; 2329f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2339f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 23423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 23523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Create a complex Item, containing multiple representations of 236acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * text, Intent, and/or URI. 23723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2389f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Item(CharSequence text, Intent intent, Uri uri) { 2399f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mText = text; 240acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = null; 241acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mIntent = intent; 242acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mUri = uri; 243acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 244acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 245acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 246acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Create a complex Item, containing multiple representations of 247acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * text, HTML text, Intent, and/or URI. If providing HTML text, you 248acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <em>must</em> supply a plain text representation as well; coercion 249acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * will not be done from HTML formated text into plain text. 250acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 251acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public Item(CharSequence text, String htmlText, Intent intent, Uri uri) { 252acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (htmlText != null && text == null) { 253acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn throw new IllegalArgumentException( 254acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn "Plain text must be supplied if HTML text is supplied"); 255acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 256acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mText = text; 257acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mHtmlText = htmlText; 2589f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mIntent = intent; 2599f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mUri = uri; 2609f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2619f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 26223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 26323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Retrieve the raw text contained in this Item. 26423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2659f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public CharSequence getText() { 2669f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mText; 2679f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2689f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 26923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 270acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Retrieve the raw HTML text contained in this Item. 271acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 272acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public String getHtmlText() { 273acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return mHtmlText; 274acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 275acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 276acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 27723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Retrieve the raw Intent contained in this Item. 27823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2799f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Intent getIntent() { 2809f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mIntent; 2819f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2829f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 28323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 28423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Retrieve the raw URI contained in this Item. 28523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 2869f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Uri getUri() { 2879f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mUri; 2889f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 28923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 29023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn /** 29123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * Turn this item into text, regardless of the type of data it 29223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * actually contains. 29323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 29423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p>The algorithm for deciding what text to return is: 29523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <ul> 29623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> If {@link #getText} is non-null, return that. 29723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> If {@link #getUri} is non-null, try to retrieve its data 29823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * as a text stream from its content provider. If this succeeds, copy 29923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the text into a String and return it. If it is not a content: URI or 30023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the content provider does not supply a text representation, return 30123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * the raw URI as a string. 30223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> If {@link #getIntent} is non-null, convert that to an intent: 303acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * URI and return it. 30423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <li> Otherwise, return an empty string. 30523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * </ul> 30623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 30723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @param context The caller's Context, from which its ContentResolver 30823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * and other things can be retrieved. 30923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @return Returns the item's textual representation. 31023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn */ 31123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn//BEGIN_INCLUDE(coerceToText) 31223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn public CharSequence coerceToText(Context context) { 31323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // If this Item has an explicit textual value, simply return that. 314acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence text = getText(); 315acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text != null) { 316acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 31723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 31823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 31923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // If this Item has a URI value, try using that. 320acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Uri uri = getUri(); 321acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (uri != null) { 32223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 32323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // First see if the URI can be opened as a plain text stream 32423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // (of any sub-type). If so, this is the best textual 32523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // representation for it. 32623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn FileInputStream stream = null; 32723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 32823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Ask for a stream of the desired type. 32923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn AssetFileDescriptor descr = context.getContentResolver() 330acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn .openTypedAssetFileDescriptor(uri, "text/*", null); 33123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn stream = descr.createInputStream(); 33223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn InputStreamReader reader = new InputStreamReader(stream, "UTF-8"); 33323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 33423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Got it... copy the stream into a local string and return it. 33523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn StringBuilder builder = new StringBuilder(128); 33623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn char[] buffer = new char[8192]; 33723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn int len; 33823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn while ((len=reader.read(buffer)) > 0) { 33923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn builder.append(buffer, 0, len); 34023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 34123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return builder.toString(); 34223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 34323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (FileNotFoundException e) { 34423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Unable to open content URI as text... not really an 34523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // error, just something to ignore. 34623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 34723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (IOException e) { 34823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Something bad has happened. 34923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn Log.w("ClippedData", "Failure loading text", e); 35023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return e.toString(); 35123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 35223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } finally { 35323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn if (stream != null) { 35423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn try { 35523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn stream.close(); 35623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } catch (IOException e) { 35723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 35823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 35923fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 36023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 36123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // If we couldn't open the URI as a stream, then the URI itself 36223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // probably serves fairly well as a textual representation. 363acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uri.toString(); 36423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 36523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 36623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Finally, if all we have is an Intent, then we can just turn that 36723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // into text. Not the most user-friendly thing, but it's something. 368acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Intent intent = getIntent(); 369acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (intent != null) { 370acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return intent.toUri(Intent.URI_INTENT_SCHEME); 37123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 37223fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn 37323fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn // Shouldn't get here, but just in case... 37423fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn return ""; 37523fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn } 37623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn//END_INCLUDE(coerceToText) 37721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 378acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 379acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Like {@link #coerceToHtmlText(Context)}, but any text that would 380acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * be returned as HTML formatting will be returned as text with 381acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * style spans. 382acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param context The caller's Context, from which its ContentResolver 383acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * and other things can be retrieved. 384acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns the item's textual representation. 385acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 386acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public CharSequence coerceToStyledText(Context context) { 387acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence text = getText(); 388acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text instanceof Spanned) { 389acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 390acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 391acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String htmlText = getHtmlText(); 392acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (htmlText != null) { 393acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn try { 394acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence newText = Html.fromHtml(htmlText); 395acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (newText != null) { 396acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return newText; 397acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 398acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (RuntimeException e) { 399acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If anything bad happens, we'll fall back on the plain text. 400acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 401acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 402acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 403acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text != null) { 404acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 405acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 406acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return coerceToHtmlOrStyledText(context, true); 407acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 408acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 409acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 410acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Turn this item into HTML text, regardless of the type of data it 411acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * actually contains. 412acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * 413acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <p>The algorithm for deciding what text to return is: 414acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <ul> 415acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> If {@link #getHtmlText} is non-null, return that. 416acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> If {@link #getText} is non-null, return that, converting to 417acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * valid HTML text. If this text contains style spans, 418acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * {@link Html#toHtml(Spanned) Html.toHtml(Spanned)} is used to 419acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * convert them to HTML formatting. 420acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> If {@link #getUri} is non-null, try to retrieve its data 421acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * as a text stream from its content provider. If the provider can 422acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * supply text/html data, that will be preferred and returned as-is. 423acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Otherwise, any text/* data will be returned and escaped to HTML. 424acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * If it is not a content: URI or the content provider does not supply 425acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * a text representation, HTML text containing a link to the URI 426acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * will be returned. 427acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> If {@link #getIntent} is non-null, convert that to an intent: 428acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * URI and return as an HTML link. 429acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * <li> Otherwise, return an empty string. 430acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * </ul> 431acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * 432acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param context The caller's Context, from which its ContentResolver 433acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * and other things can be retrieved. 434acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns the item's representation as HTML text. 435acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 436acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn public String coerceToHtmlText(Context context) { 437acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If the item has an explicit HTML value, simply return that. 438acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String htmlText = getHtmlText(); 439acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (htmlText != null) { 440acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return htmlText; 441acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 442acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 443acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If this Item has a plain text value, return it as HTML. 444acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence text = getText(); 445acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text != null) { 446acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (text instanceof Spanned) { 447acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return Html.toHtml((Spanned)text); 448acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 449acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return Html.escapeHtml(text); 450acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 451acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 452acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn text = coerceToHtmlOrStyledText(context, false); 453acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text != null ? text.toString() : null; 454acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 455acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 456acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn private CharSequence coerceToHtmlOrStyledText(Context context, boolean styled) { 457acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If this Item has a URI value, try using that. 458acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (mUri != null) { 459acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 460acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Check to see what data representations the content 461acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // provider supports. We would like HTML text, but if that 462acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // is not possible we'll live with plan text. 463acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String[] types = context.getContentResolver().getStreamTypes(mUri, "text/*"); 464acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn boolean hasHtml = false; 465acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn boolean hasText = false; 466acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (types != null) { 467acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn for (String type : types) { 468acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if ("text/html".equals(type)) { 469acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn hasHtml = true; 470acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else if (type.startsWith("text/")) { 471acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn hasText = true; 472acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 473acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 474acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 475acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 476acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If the provider can serve data we can use, open and load it. 477acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (hasHtml || hasText) { 478acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn FileInputStream stream = null; 479acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn try { 480acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Ask for a stream of the desired type. 481acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn AssetFileDescriptor descr = context.getContentResolver() 482acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn .openTypedAssetFileDescriptor(mUri, 483acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn hasHtml ? "text/html" : "text/plain", null); 484acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn stream = descr.createInputStream(); 485acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn InputStreamReader reader = new InputStreamReader(stream, "UTF-8"); 486acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 487acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Got it... copy the stream into a local string and return it. 488acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn StringBuilder builder = new StringBuilder(128); 489acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn char[] buffer = new char[8192]; 490acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn int len; 491acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn while ((len=reader.read(buffer)) > 0) { 492acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append(buffer, 0, len); 493acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 494acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String text = builder.toString(); 495acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (hasHtml) { 496acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (styled) { 497acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // We loaded HTML formatted text and the caller 498acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // want styled text, convert it. 499acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn try { 500acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn CharSequence newText = Html.fromHtml(text); 501acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return newText != null ? newText : text; 502acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (RuntimeException e) { 503acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 504acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 505acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else { 506acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // We loaded HTML formatted text and that is what 507acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // the caller wants, just return it. 508acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text.toString(); 509acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 510acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 511acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (styled) { 512acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // We loaded plain text and the caller wants styled 513acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // text, that is all we have so return it. 514acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return text; 515acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else { 516acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // We loaded plain text and the caller wants HTML 517acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // text, escape it for HTML. 518acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return Html.escapeHtml(text); 519acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 520acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 521acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (FileNotFoundException e) { 522acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Unable to open content URI as text... not really an 523acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // error, just something to ignore. 524acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 525acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (IOException e) { 526acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Something bad has happened. 527acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Log.w("ClippedData", "Failure loading text", e); 528acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return Html.escapeHtml(e.toString()); 529acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 530acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } finally { 531acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (stream != null) { 532acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn try { 533acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn stream.close(); 534acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } catch (IOException e) { 535acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 536acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 537acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 538acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 539acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 540acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // If we couldn't open the URI as a stream, then we can build 541acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // some HTML text with the URI itself. 542acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // probably serves fairly well as a textual representation. 543acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (styled) { 544acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uriToStyledText(mUri.toString()); 545acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else { 546acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uriToHtml(mUri.toString()); 547acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 548acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 549acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 550acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Finally, if all we have is an Intent, then we can just turn that 551acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // into text. Not the most user-friendly thing, but it's something. 552acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (mIntent != null) { 553acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (styled) { 554acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uriToStyledText(mIntent.toUri(Intent.URI_INTENT_SCHEME)); 555acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else { 556acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return uriToHtml(mIntent.toUri(Intent.URI_INTENT_SCHEME)); 557acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 558acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 559acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 560acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn // Shouldn't get here, but just in case... 561acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return ""; 562acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 563acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 564acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn private String uriToHtml(String uri) { 565acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn StringBuilder builder = new StringBuilder(256); 566acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append("<a href=\""); 567c92db391379cc19738de8bb5008ed619cb049ebeNick Kralevich builder.append(Html.escapeHtml(uri)); 568acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append("\">"); 569acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append(Html.escapeHtml(uri)); 570acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append("</a>"); 571acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return builder.toString(); 572acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 573acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 574acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn private CharSequence uriToStyledText(String uri) { 575acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn SpannableStringBuilder builder = new SpannableStringBuilder(); 576acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.append(uri); 577acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn builder.setSpan(new URLSpan(uri), 0, builder.length(), 578acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 579acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return builder; 580acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 581acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 58221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn @Override 58321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public String toString() { 58421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn StringBuilder b = new StringBuilder(128); 58521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 58621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("ClipData.Item { "); 58721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn toShortString(b); 58821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(" }"); 58921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 59021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn return b.toString(); 59121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 59221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 59321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn /** @hide */ 59421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public void toShortString(StringBuilder b) { 595acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn if (mHtmlText != null) { 596acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn b.append("H:"); 597acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn b.append(mHtmlText); 598acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } else if (mText != null) { 59921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("T:"); 60021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(mText); 60121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } else if (mUri != null) { 60221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("U:"); 60321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(mUri); 60421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } else if (mIntent != null) { 60521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("I:"); 60621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mIntent.toShortString(b, true, true, true, true); 60721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } else { 60821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("NULL"); 60921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 61021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 6119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 6129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 6139f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** 6149f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Create a new clip. 6159f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 6169f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * @param label Label to show to the user describing this clip. 6171040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param mimeTypes An array of MIME types this data is available as. 6189f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * @param item The contents of the first item in the clip. 6199f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 620327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public ClipData(CharSequence label, String[] mimeTypes, Item item) { 621f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mClipDescription = new ClipDescription(label, mimeTypes); 622f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn if (item == null) { 623f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn throw new NullPointerException("item is null"); 624f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn } 625327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn mIcon = null; 62621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems = new ArrayList<Item>(); 627f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mItems.add(item); 628f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn } 629f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn 630f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn /** 631f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Create a new clip. 632f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * 633f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * @param description The ClipDescription describing the clip contents. 634f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * @param item The contents of the first item in the clip. 635f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn */ 636327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public ClipData(ClipDescription description, Item item) { 637f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mClipDescription = description; 6389f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (item == null) { 6399f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn throw new NullPointerException("item is null"); 6409f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 641327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn mIcon = null; 64221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems = new ArrayList<Item>(); 6439f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mItems.add(item); 6449f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 6459f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 6461040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 64721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn * Create a new clip that is a copy of another clip. This does a deep-copy 64821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn * of all items in the clip. 64921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn * 65021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn * @param other The existing ClipData that is to be copied. 65121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn */ 65221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public ClipData(ClipData other) { 65321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mClipDescription = other.mClipDescription; 65421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mIcon = other.mIcon; 65521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems = new ArrayList<Item>(other.mItems); 65621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 65721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 65821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn /** 659f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Create a new ClipData holding data of the type 660f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_PLAIN}. 6611040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 6621040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param label User-visible label for the clip data. 6631040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param text The actual text in the clip. 6641040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @return Returns a new ClipData containing the specified data. 6651040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 666327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn static public ClipData newPlainText(CharSequence label, CharSequence text) { 6671040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn Item item = new Item(text); 668327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return new ClipData(label, MIMETYPES_TEXT_PLAIN, item); 669327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn } 670327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn 6711040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 672acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * Create a new ClipData holding data of the type 673acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_HTML}. 674acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * 675acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param label User-visible label for the clip data. 676acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param text The text of clip as plain text, for receivers that don't 677acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * handle HTML. This is required. 678acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @param htmlText The actual HTML text in the clip. 679acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn * @return Returns a new ClipData containing the specified data. 680acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn */ 681acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn static public ClipData newHtmlText(CharSequence label, CharSequence text, 682acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String htmlText) { 683acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn Item item = new Item(text, htmlText); 684acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn return new ClipData(label, MIMETYPES_TEXT_HTML, item); 685acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn } 686acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn 687acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn /** 688f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Create a new ClipData holding an Intent with MIME type 689f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_INTENT}. 6901040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 6911040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param label User-visible label for the clip data. 6921040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param intent The actual Intent in the clip. 6931040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @return Returns a new ClipData containing the specified data. 6941040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 695327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn static public ClipData newIntent(CharSequence label, Intent intent) { 6961040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn Item item = new Item(intent); 697327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return new ClipData(label, MIMETYPES_TEXT_INTENT, item); 6981040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 6991040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn 7001040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 7011040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * Create a new ClipData holding a URI. If the URI is a content: URI, 7021040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * this will query the content provider for the MIME type of its data and 7031040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * use that as the MIME type. Otherwise, it will use the MIME type 704f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_URILIST}. 7051040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 7061040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param resolver ContentResolver used to get information about the URI. 7071040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param label User-visible label for the clip data. 7081040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param uri The URI in the clip. 7091040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @return Returns a new ClipData containing the specified data. 7101040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 7111040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn static public ClipData newUri(ContentResolver resolver, CharSequence label, 712327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn Uri uri) { 7131040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn Item item = new Item(uri); 7141040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn String[] mimeTypes = null; 7151040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if ("content".equals(uri.getScheme())) { 7161040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn String realType = resolver.getType(uri); 7171040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mimeTypes = resolver.getStreamTypes(uri, "*/*"); 7181040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if (mimeTypes == null) { 7191040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if (realType != null) { 720f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mimeTypes = new String[] { realType, ClipDescription.MIMETYPE_TEXT_URILIST }; 7211040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7221040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } else { 7231040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn String[] tmp = new String[mimeTypes.length + (realType != null ? 2 : 1)]; 7241040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn int i = 0; 7251040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if (realType != null) { 7261040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn tmp[0] = realType; 7271040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn i++; 7281040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7291040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn System.arraycopy(mimeTypes, 0, tmp, i, mimeTypes.length); 730f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn tmp[i + mimeTypes.length] = ClipDescription.MIMETYPE_TEXT_URILIST; 7311040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mimeTypes = tmp; 7321040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7331040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7341040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn if (mimeTypes == null) { 7351040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mimeTypes = MIMETYPES_TEXT_URILIST; 7361040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 737327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return new ClipData(label, mimeTypes, item); 7381040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7391040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn 7401040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 741f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Create a new ClipData holding an URI with MIME type 742f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * {@link ClipDescription#MIMETYPE_TEXT_URILIST}. 743327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * Unlike {@link #newUri(ContentResolver, CharSequence, Uri)}, nothing 7441040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * is inferred about the URI -- if it is a content: URI holding a bitmap, 7451040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * the reported type will still be uri-list. Use this with care! 7461040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * 7471040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param label User-visible label for the clip data. 7481040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @param uri The URI in the clip. 7491040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @return Returns a new ClipData containing the specified data. 7501040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 751327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn static public ClipData newRawUri(CharSequence label, Uri uri) { 7521040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn Item item = new Item(uri); 753327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return new ClipData(label, MIMETYPES_TEXT_URILIST, item); 7541040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 7551040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn 756f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn /** 757f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * Return the {@link ClipDescription} associated with this data, describing 758f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn * what it contains. 759f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn */ 760f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn public ClipDescription getDescription() { 761f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn return mClipDescription; 762f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn } 763f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn 764327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn /** 765327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * Add a new Item to the overall ClipData container. 766327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn */ 7679f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void addItem(Item item) { 7689f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (item == null) { 7699f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn throw new NullPointerException("item is null"); 7709f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7719f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mItems.add(item); 7729f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7739f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 774327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn /** @hide */ 7759f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public Bitmap getIcon() { 7769f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mIcon; 7779f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7789f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 779327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn /** 780327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * Return the number of items in the clip data. 781327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn */ 7829f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public int getItemCount() { 7839f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mItems.size(); 7849f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7859f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 786327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn /** 787327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * Return a single item inside of the clip data. The index can range 788327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn * from 0 to {@link #getItemCount()}-1. 789327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn */ 790327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public Item getItemAt(int index) { 7919f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return mItems.get(index); 7929f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 7939f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 794a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey /** 795a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * Prepare this {@link ClipData} to leave an app process. 796a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * 797a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey * @hide 798a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey */ 799a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey public void prepareToLeaveProcess() { 800a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey final int size = mItems.size(); 801a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey for (int i = 0; i < size; i++) { 802a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey final Item item = mItems.get(i); 803a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey if (item.mIntent != null) { 804a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey item.mIntent.prepareToLeaveProcess(); 805a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey } 806a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey if (item.mUri != null && StrictMode.vmFileUriExposureEnabled()) { 807a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey item.mUri.checkFileUriExposed("ClipData.Item.getUri()"); 808a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey } 809a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey } 810a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey } 811a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey 8129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn @Override 81321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public String toString() { 81421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn StringBuilder b = new StringBuilder(128); 81521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 81621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("ClipData { "); 81721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn toShortString(b); 81821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(" }"); 81921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 82021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn return b.toString(); 82121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 82221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 82321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn /** @hide */ 82421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn public void toShortString(StringBuilder b) { 82521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn boolean first; 82621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn if (mClipDescription != null) { 82721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn first = !mClipDescription.toShortString(b); 82821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } else { 82921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn first = true; 83021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 83121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn if (mIcon != null) { 83221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn if (!first) { 83321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(' '); 83421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 83521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn first = false; 83621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append("I:"); 83721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(mIcon.getWidth()); 83821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append('x'); 83921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(mIcon.getHeight()); 84021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 84121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn for (int i=0; i<mItems.size(); i++) { 84221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn if (!first) { 84321c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append(' '); 84421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 84521c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn first = false; 84621c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append('{'); 84721c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems.get(i).toShortString(b); 84821c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn b.append('}'); 84921c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 85021c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn } 85121c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn 85221c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn @Override 8539f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public int describeContents() { 8549f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return 0; 8559f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8569f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 8579f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn @Override 8589f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void writeToParcel(Parcel dest, int flags) { 859f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mClipDescription.writeToParcel(dest, flags); 8609f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (mIcon != null) { 8619f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(1); 8629f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mIcon.writeToParcel(dest, flags); 8639f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } else { 8649f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(0); 8659f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8669f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn final int N = mItems.size(); 8679f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(N); 8689f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn for (int i=0; i<N; i++) { 8699f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn Item item = mItems.get(i); 8709f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn TextUtils.writeToParcel(item.mText, dest, flags); 871acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn dest.writeString(item.mHtmlText); 8729f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (item.mIntent != null) { 8739f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(1); 8749f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn item.mIntent.writeToParcel(dest, flags); 8759f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } else { 8769f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(0); 8779f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8789f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (item.mUri != null) { 8799f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(1); 8809f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn item.mUri.writeToParcel(dest, flags); 8819f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } else { 8829f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn dest.writeInt(0); 8839f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8849f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8859f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 8869f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 8871040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn ClipData(Parcel in) { 888f834dfabbcbbe1f209682f18c67f2e8b9d3e1dd7Dianne Hackborn mClipDescription = new ClipDescription(in); 8899f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (in.readInt() != 0) { 8909f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mIcon = Bitmap.CREATOR.createFromParcel(in); 8911040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } else { 8921040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn mIcon = null; 8939f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 89421c241e061de29a538008ca42df9c878184bcfb8Dianne Hackborn mItems = new ArrayList<Item>(); 8959f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn final int N = in.readInt(); 8969f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn for (int i=0; i<N; i++) { 8979f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 898acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn String htmlText = in.readString(); 8999f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn Intent intent = in.readInt() != 0 ? Intent.CREATOR.createFromParcel(in) : null; 9009f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn Uri uri = in.readInt() != 0 ? Uri.CREATOR.createFromParcel(in) : null; 901acb69bb909d098cea284df47d794c17171d84c91Dianne Hackborn mItems.add(new Item(text, htmlText, intent, uri)); 9029f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 9039f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 9049f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 9051040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public static final Parcelable.Creator<ClipData> CREATOR = 9061040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn new Parcelable.Creator<ClipData>() { 9079f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 9081040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public ClipData createFromParcel(Parcel source) { 9091040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn return new ClipData(source); 9109f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 9119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 9121040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public ClipData[] newArray(int size) { 9131040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn return new ClipData[size]; 9149f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 9159f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn }; 9169f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn} 917