1package android.content.pm; 2 3import android.content.IntentFilter; 4import android.graphics.drawable.Drawable; 5import android.os.Parcel; 6import android.os.Parcelable; 7import android.text.TextUtils; 8import android.util.Printer; 9 10import java.text.Collator; 11import java.util.Comparator; 12 13/** 14 * Information that is returned from resolving an intent 15 * against an IntentFilter. This partially corresponds to 16 * information collected from the AndroidManifest.xml's 17 * <intent> tags. 18 */ 19public class ResolveInfo implements Parcelable { 20 /** 21 * The activity that corresponds to this resolution match, if this 22 * resolution is for an activity. One and only one of this and 23 * serviceInfo must be non-null. 24 */ 25 public ActivityInfo activityInfo; 26 27 /** 28 * The service that corresponds to this resolution match, if this 29 * resolution is for a service. One and only one of this and 30 * activityInfo must be non-null. 31 */ 32 public ServiceInfo serviceInfo; 33 34 /** 35 * The IntentFilter that was matched for this ResolveInfo. 36 */ 37 public IntentFilter filter; 38 39 /** 40 * The declared priority of this match. Comes from the "priority" 41 * attribute or, if not set, defaults to 0. Higher values are a higher 42 * priority. 43 */ 44 public int priority; 45 46 /** 47 * Order of result according to the user's preference. If the user 48 * has not set a preference for this result, the value is 0; higher 49 * values are a higher priority. 50 */ 51 public int preferredOrder; 52 53 /** 54 * The system's evaluation of how well the activity matches the 55 * IntentFilter. This is a match constant, a combination of 56 * {@link IntentFilter#MATCH_CATEGORY_MASK IntentFilter.MATCH_CATEGORY_MASK} 57 * and {@link IntentFilter#MATCH_ADJUSTMENT_MASK IntentFiler.MATCH_ADJUSTMENT_MASK}. 58 */ 59 public int match; 60 61 /** 62 * Only set when returned by 63 * {@link PackageManager#queryIntentActivityOptions}, this tells you 64 * which of the given specific intents this result came from. 0 is the 65 * first in the list, < 0 means it came from the generic Intent query. 66 */ 67 public int specificIndex = -1; 68 69 /** 70 * This filter has specified the Intent.CATEGORY_DEFAULT, meaning it 71 * would like to be considered a default action that the user can 72 * perform on this data. 73 */ 74 public boolean isDefault; 75 76 /** 77 * A string resource identifier (in the package's resources) of this 78 * match's label. From the "label" attribute or, if not set, 0. 79 */ 80 public int labelRes; 81 82 /** 83 * The actual string retrieve from <var>labelRes</var> or null if none 84 * was provided. 85 */ 86 public CharSequence nonLocalizedLabel; 87 88 /** 89 * A drawable resource identifier (in the package's resources) of this 90 * match's icon. From the "icon" attribute or, if not set, 0. 91 */ 92 public int icon; 93 94 /** 95 * Optional -- if non-null, the {@link #labelRes} and {@link #icon} 96 * resources will be loaded from this package, rather than the one 97 * containing the resolved component. 98 */ 99 public String resolvePackageName; 100 101 /** 102 * Retrieve the current textual label associated with this resolution. This 103 * will call back on the given PackageManager to load the label from 104 * the application. 105 * 106 * @param pm A PackageManager from which the label can be loaded; usually 107 * the PackageManager from which you originally retrieved this item. 108 * 109 * @return Returns a CharSequence containing the resolutions's label. If the 110 * item does not have a label, its name is returned. 111 */ 112 public CharSequence loadLabel(PackageManager pm) { 113 if (nonLocalizedLabel != null) { 114 return nonLocalizedLabel; 115 } 116 CharSequence label; 117 if (resolvePackageName != null && labelRes != 0) { 118 label = pm.getText(resolvePackageName, labelRes, null); 119 if (label != null) { 120 return label; 121 } 122 } 123 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo; 124 ApplicationInfo ai = ci.applicationInfo; 125 if (labelRes != 0) { 126 label = pm.getText(ci.packageName, labelRes, ai); 127 if (label != null) { 128 return label; 129 } 130 } 131 return ci.loadLabel(pm); 132 } 133 134 /** 135 * Retrieve the current graphical icon associated with this resolution. This 136 * will call back on the given PackageManager to load the icon from 137 * the application. 138 * 139 * @param pm A PackageManager from which the icon can be loaded; usually 140 * the PackageManager from which you originally retrieved this item. 141 * 142 * @return Returns a Drawable containing the resolution's icon. If the 143 * item does not have an icon, the default activity icon is returned. 144 */ 145 public Drawable loadIcon(PackageManager pm) { 146 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo; 147 ApplicationInfo ai = ci.applicationInfo; 148 Drawable dr; 149 if (resolvePackageName != null && icon != 0) { 150 dr = pm.getDrawable(resolvePackageName, icon, null); 151 if (dr != null) { 152 return dr; 153 } 154 } 155 if (icon != 0) { 156 dr = pm.getDrawable(ci.packageName, icon, ai); 157 if (dr != null) { 158 return dr; 159 } 160 } 161 return ci.loadIcon(pm); 162 } 163 164 /** 165 * Return the icon resource identifier to use for this match. If the 166 * match defines an icon, that is used; else if the activity defines 167 * an icon, that is used; else, the application icon is used. 168 * 169 * @return The icon associated with this match. 170 */ 171 public final int getIconResource() { 172 if (icon != 0) return icon; 173 if (activityInfo != null) return activityInfo.getIconResource(); 174 if (serviceInfo != null) return serviceInfo.getIconResource(); 175 return 0; 176 } 177 178 public void dump(Printer pw, String prefix) { 179 if (filter != null) { 180 pw.println(prefix + "Filter:"); 181 filter.dump(pw, prefix + " "); 182 } 183 pw.println(prefix + "priority=" + priority 184 + " preferredOrder=" + preferredOrder 185 + " match=0x" + Integer.toHexString(match) 186 + " specificIndex=" + specificIndex 187 + " isDefault=" + isDefault); 188 if (resolvePackageName != null) { 189 pw.println(prefix + "resolvePackageName=" + resolvePackageName); 190 } 191 if (labelRes != 0 || nonLocalizedLabel != null || icon != 0) { 192 pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes) 193 + " nonLocalizedLabel=" + nonLocalizedLabel 194 + " icon=0x" + Integer.toHexString(icon)); 195 } 196 if (activityInfo != null) { 197 pw.println(prefix + "ActivityInfo:"); 198 activityInfo.dump(pw, prefix + " "); 199 } else if (serviceInfo != null) { 200 pw.println(prefix + "ServiceInfo:"); 201 serviceInfo.dump(pw, prefix + " "); 202 } 203 } 204 205 public ResolveInfo() { 206 } 207 208 public String toString() { 209 ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo; 210 return "ResolveInfo{" 211 + Integer.toHexString(System.identityHashCode(this)) 212 + " " + ci.name + " p=" + priority + " o=" 213 + preferredOrder + " m=0x" + Integer.toHexString(match) + "}"; 214 } 215 216 public int describeContents() { 217 return 0; 218 } 219 220 public void writeToParcel(Parcel dest, int parcelableFlags) { 221 if (activityInfo != null) { 222 dest.writeInt(1); 223 activityInfo.writeToParcel(dest, parcelableFlags); 224 } else if (serviceInfo != null) { 225 dest.writeInt(2); 226 serviceInfo.writeToParcel(dest, parcelableFlags); 227 } else { 228 dest.writeInt(0); 229 } 230 if (filter != null) { 231 dest.writeInt(1); 232 filter.writeToParcel(dest, parcelableFlags); 233 } else { 234 dest.writeInt(0); 235 } 236 dest.writeInt(priority); 237 dest.writeInt(preferredOrder); 238 dest.writeInt(match); 239 dest.writeInt(specificIndex); 240 dest.writeInt(labelRes); 241 TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags); 242 dest.writeInt(icon); 243 dest.writeString(resolvePackageName); 244 } 245 246 public static final Creator<ResolveInfo> CREATOR 247 = new Creator<ResolveInfo>() { 248 public ResolveInfo createFromParcel(Parcel source) { 249 return new ResolveInfo(source); 250 } 251 public ResolveInfo[] newArray(int size) { 252 return new ResolveInfo[size]; 253 } 254 }; 255 256 private ResolveInfo(Parcel source) { 257 switch (source.readInt()) { 258 case 1: 259 activityInfo = ActivityInfo.CREATOR.createFromParcel(source); 260 serviceInfo = null; 261 break; 262 case 2: 263 serviceInfo = ServiceInfo.CREATOR.createFromParcel(source); 264 activityInfo = null; 265 break; 266 default: 267 activityInfo = null; 268 serviceInfo = null; 269 break; 270 } 271 if (source.readInt() != 0) { 272 filter = IntentFilter.CREATOR.createFromParcel(source); 273 } 274 priority = source.readInt(); 275 preferredOrder = source.readInt(); 276 match = source.readInt(); 277 specificIndex = source.readInt(); 278 labelRes = source.readInt(); 279 nonLocalizedLabel 280 = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 281 icon = source.readInt(); 282 resolvePackageName = source.readString(); 283 } 284 285 public static class DisplayNameComparator 286 implements Comparator<ResolveInfo> { 287 public DisplayNameComparator(PackageManager pm) { 288 mPM = pm; 289 } 290 291 public final int compare(ResolveInfo a, ResolveInfo b) { 292 CharSequence sa = a.loadLabel(mPM); 293 if (sa == null) sa = a.activityInfo.name; 294 CharSequence sb = b.loadLabel(mPM); 295 if (sb == null) sb = b.activityInfo.name; 296 297 return sCollator.compare(sa.toString(), sb.toString()); 298 } 299 300 private final Collator sCollator = Collator.getInstance(); 301 private PackageManager mPM; 302 } 303} 304