• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package android.content.pm;
2 
3 import android.content.IntentFilter;
4 import android.graphics.drawable.Drawable;
5 import android.os.Parcel;
6 import android.os.Parcelable;
7 import android.text.TextUtils;
8 import android.util.Printer;
9 
10 import java.text.Collator;
11 import 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  */
19 public 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      */
loadLabel(PackageManager pm)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      */
loadIcon(PackageManager pm)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      */
getIconResource()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 
dump(Printer pw, String prefix)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 
ResolveInfo()205     public ResolveInfo() {
206     }
207 
toString()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 
describeContents()216     public int describeContents() {
217         return 0;
218     }
219 
writeToParcel(Parcel dest, int parcelableFlags)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 
ResolveInfo(Parcel source)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> {
DisplayNameComparator(PackageManager pm)287         public DisplayNameComparator(PackageManager pm) {
288             mPM = pm;
289         }
290 
compare(ResolveInfo a, ResolveInfo b)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