Grokking Android

Getting Down to the Nitty Gritty of Android Development

Checking Intent Availability in Android

By

Intents are probably Android's most powerful tool. They tie together loosely coupled components and make it possible to start Activities that are not part of your own app. Using intents you can delegate to the Contacts app to select a contact or you can start the browser, share data and so on.

The receiving apps declare intent filters which describe the intents its component react to. If you know which intent filters the app provides and if the components are publicly available you can start any Activity of any app on the users device.

The problem is: How do you know if the app is installed - if you can use the Intent?

The solution is to create the Intent and check if it is available:


public static boolean isAvailable(Context ctx, Intent intent) {
   final PackageManager mgr = ctx.getPackageManager();
   List<ResolveInfo> list =
      mgr.queryIntentActivities(intent, 
         PackageManager.MATCH_DEFAULT_ONLY);
   return list.size() > 0;
}

This solution is based on Romain Guy's implementation on Android's developer blog, which he originally posted on his blog. Lars Vogel has published a similar solution. Alas, the original code does not work - at least not in all circumstances.

The difference between +Romain Guy's and +Lars Vogel's code and mine is the intent used to determine the correct package. While Romain and Lars create a new Intent based solely on the action used (e.g. ACTION_SHARE), the code above uses a fully-fledged Intent object. Ideally it's the one, that you would also use to start the Activity.

But does this make a difference? It does indeed. I noticed that the original code has issues when I wanted to use ACTION_SEND. In this case the PackageManager returns an empty list if you only use the action. The problem is the missing mime type. If you add the mime type and use my variant, the PackageManager returns a list of applications that can be used. On the original blog entry +Alexey Volovoy also mentioned this problem in a comment a while ago.

Another solution is by +Reto Meier. He uses the Intent object itself to check if an Activity is available for this object. He uses the Intent's method resolveActivity(). You can find the full solution in his book.

So I assume my approach with using the Intent object itself is sound. But Romain and Lars are very experienced and renowned Android developers, Romain is even on the Android team. So it might very well be that I miss something. If you know any circumstances, where my solution would run into problems or where the original proposal works better, please let me know in the comments section.

Update: Lars Vogel has updated his tutorial.

Wolfram Rittmeyer lives in Germany and has been developing with Java for many years.

He has been interested in Android for quite a while and has been blogging about all kind of topics around Android.

You can find him on Google+ and Twitter.