ClipDescription.java revision 21c241e061de29a538008ca42df9c878184bcfb8
1/** 2 * Copyright (c) 2010, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.content; 18 19import android.os.Parcel; 20import android.os.Parcelable; 21import android.text.TextUtils; 22 23import java.util.ArrayList; 24 25/** 26 * Meta-data describing the contents of a {@link ClipData}. Provides enough 27 * information to know if you can handle the ClipData, but not the data 28 * itself. 29 * 30 * <div class="special reference"> 31 * <h3>Developer Guides</h3> 32 * <p>For more information about using the clipboard framework, read the 33 * <a href="{@docRoot}guide/topics/clipboard/copy-paste.html">Copy and Paste</a> 34 * developer guide.</p> 35 * </div> 36 */ 37public class ClipDescription implements Parcelable { 38 /** 39 * The MIME type for a clip holding plain text. 40 */ 41 public static final String MIMETYPE_TEXT_PLAIN = "text/plain"; 42 43 /** 44 * The MIME type for a clip holding one or more URIs. This should be 45 * used for URIs that are meaningful to a user (such as an http: URI). 46 * It should <em>not</em> be used for a content: URI that references some 47 * other piece of data; in that case the MIME type should be the type 48 * of the referenced data. 49 */ 50 public static final String MIMETYPE_TEXT_URILIST = "text/uri-list"; 51 52 /** 53 * The MIME type for a clip holding an Intent. 54 */ 55 public static final String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent"; 56 57 final CharSequence mLabel; 58 final String[] mMimeTypes; 59 60 /** 61 * Create a new clip. 62 * 63 * @param label Label to show to the user describing this clip. 64 * @param mimeTypes An array of MIME types this data is available as. 65 */ 66 public ClipDescription(CharSequence label, String[] mimeTypes) { 67 if (mimeTypes == null) { 68 throw new NullPointerException("mimeTypes is null"); 69 } 70 mLabel = label; 71 mMimeTypes = mimeTypes; 72 } 73 74 /** 75 * Create a copy of a ClipDescription. 76 */ 77 public ClipDescription(ClipDescription o) { 78 mLabel = o.mLabel; 79 mMimeTypes = o.mMimeTypes; 80 } 81 82 /** 83 * Helper to compare two MIME types, where one may be a pattern. 84 * @param concreteType A fully-specified MIME type. 85 * @param desiredType A desired MIME type that may be a pattern such as *\/*. 86 * @return Returns true if the two MIME types match. 87 */ 88 public static boolean compareMimeTypes(String concreteType, String desiredType) { 89 final int typeLength = desiredType.length(); 90 if (typeLength == 3 && desiredType.equals("*/*")) { 91 return true; 92 } 93 94 final int slashpos = desiredType.indexOf('/'); 95 if (slashpos > 0) { 96 if (typeLength == slashpos+2 && desiredType.charAt(slashpos+1) == '*') { 97 if (desiredType.regionMatches(0, concreteType, 0, slashpos+1)) { 98 return true; 99 } 100 } else if (desiredType.equals(concreteType)) { 101 return true; 102 } 103 } 104 105 return false; 106 } 107 108 /** 109 * Return the label for this clip. 110 */ 111 public CharSequence getLabel() { 112 return mLabel; 113 } 114 115 /** 116 * Check whether the clip description contains the given MIME type. 117 * 118 * @param mimeType The desired MIME type. May be a pattern. 119 * @return Returns true if one of the MIME types in the clip description 120 * matches the desired MIME type, else false. 121 */ 122 public boolean hasMimeType(String mimeType) { 123 for (int i=0; i<mMimeTypes.length; i++) { 124 if (compareMimeTypes(mMimeTypes[i], mimeType)) { 125 return true; 126 } 127 } 128 return false; 129 } 130 131 /** 132 * Filter the clip description MIME types by the given MIME type. Returns 133 * all MIME types in the clip that match the given MIME type. 134 * 135 * @param mimeType The desired MIME type. May be a pattern. 136 * @return Returns an array of all matching MIME types. If there are no 137 * matching MIME types, null is returned. 138 */ 139 public String[] filterMimeTypes(String mimeType) { 140 ArrayList<String> array = null; 141 for (int i=0; i<mMimeTypes.length; i++) { 142 if (compareMimeTypes(mMimeTypes[i], mimeType)) { 143 if (array == null) { 144 array = new ArrayList<String>(); 145 } 146 array.add(mMimeTypes[i]); 147 } 148 } 149 if (array == null) { 150 return null; 151 } 152 String[] rawArray = new String[array.size()]; 153 array.toArray(rawArray); 154 return rawArray; 155 } 156 157 /** 158 * Return the number of MIME types the clip is available in. 159 */ 160 public int getMimeTypeCount() { 161 return mMimeTypes.length; 162 } 163 164 /** 165 * Return one of the possible clip MIME types. 166 */ 167 public String getMimeType(int index) { 168 return mMimeTypes[index]; 169 } 170 171 /** @hide */ 172 public void validate() { 173 if (mMimeTypes == null) { 174 throw new NullPointerException("null mime types"); 175 } 176 if (mMimeTypes.length <= 0) { 177 throw new IllegalArgumentException("must have at least 1 mime type"); 178 } 179 for (int i=0; i<mMimeTypes.length; i++) { 180 if (mMimeTypes[i] == null) { 181 throw new NullPointerException("mime type at " + i + " is null"); 182 } 183 } 184 } 185 186 @Override 187 public String toString() { 188 StringBuilder b = new StringBuilder(128); 189 190 b.append("ClipDescription { "); 191 toShortString(b); 192 b.append(" }"); 193 194 return b.toString(); 195 } 196 197 /** @hide */ 198 public boolean toShortString(StringBuilder b) { 199 boolean first = true; 200 for (int i=0; i<mMimeTypes.length; i++) { 201 if (!first) { 202 b.append(' '); 203 } 204 first = false; 205 b.append(mMimeTypes[i]); 206 } 207 if (mLabel != null) { 208 if (!first) { 209 b.append(' '); 210 } 211 first = false; 212 b.append('"'); 213 b.append(mLabel); 214 b.append('"'); 215 } 216 return !first; 217 } 218 219 @Override 220 public int describeContents() { 221 return 0; 222 } 223 224 @Override 225 public void writeToParcel(Parcel dest, int flags) { 226 TextUtils.writeToParcel(mLabel, dest, flags); 227 dest.writeStringArray(mMimeTypes); 228 } 229 230 ClipDescription(Parcel in) { 231 mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); 232 mMimeTypes = in.createStringArray(); 233 } 234 235 public static final Parcelable.Creator<ClipDescription> CREATOR = 236 new Parcelable.Creator<ClipDescription>() { 237 238 public ClipDescription createFromParcel(Parcel source) { 239 return new ClipDescription(source); 240 } 241 242 public ClipDescription[] newArray(int size) { 243 return new ClipDescription[size]; 244 } 245 }; 246} 247