Resolving an Implicit Intent
In CriminalIntent, you used an implicit intent to send a crime report. You presented an activity
chooser by creating an implicit intent, wrapping it in a chooser intent, and sending it to the OS with
startActivity(Intent):
Intent i = new Intent(Intent.ACTION_SEND);
... // Create and put intent extras
i = Intent.createChooser(i, getString(R.string.send_report));
startActivity(i);
You may be wondering why you are not using that approach here. The short explanation is that the
MAIN/LAUNCHER intent filter may or may not match a MAIN/LAUNCHER implicit intent that is sent via
startActivity(Intent).
startActivity(Intent) does not mean, “Start an activity matching this implicit intent.” It
means, “Start the default activity matching this implicit intent.” When you send an implicit
intent via startActivity(Intent) (or startActivityForResult(...)), the OS secretly adds the
Intent.CATEGORY_DEFAULT category to the intent.
Thus, if you want an intent filter to match implicit intents sent via startActivity(Intent), you must
include the DEFAULT category in that intent filter.
An activity that has the MAIN/LAUNCHER intent filter is the main entry point for the app that it belongs
to. It only wants the job of main entry point for that application. It typically does not care about being
the “default” main entry point, so it does not have to include the CATEGORY_DEFAULT category.
Because MAIN/LAUNCHER intent filters may not include CATEGORY_DEFAULT, you cannot reliably match
them to an implicit intent sent via startActivity(Intent). Instead, you use the intent to query the
PackageManager directly for activities with the MAIN/LAUNCHER intent filter.
The next step is to display the labels of these activities in NerdLauncherFragment’s RecyclerView. An
activity’s label is its display name – something the user should recognize. Given that these activities
are launcher activities, the label is most likely the application name.
You can find the labels for the activities, along with other metadata, in the ResolveInfo objects that the
PackageManager returned.
First, sort the ResolveInfo objects returned from the PackageManager alphabetically by label using the
ResolveInfo.loadLabel(PackageManager) method.
Listing 24.4 Sorting alphabetically (NerdLauncherFragment.java)
public class NerdLauncherFragment extends Fragment {
...
private void setupAdapter() {
...
List
Collections.sort(activities, new Comparator
public int compare(ResolveInfo a, ResolveInfo b) {
PackageManager pm = getActivity().getPackageManager();
return String.CASE_INSENSITIVE_ORDER.compare(
a.loadLabel(pm).toString(),
b.loadLabel(pm).toString());
}
});
Log.i(TAG, "Found " + activities.size() + " activities.");
}
}