summaryrefslogtreecommitdiffstats
path: root/docs/html/resources/articles/can-i-use-this-intent.jd
blob: 7787d31e39cae943a8a69a773f238d3aca2a6c71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
page.title=Can I Use this Intent?
parent.title=Articles
parent.link=../browser.html?tag=article
@jd:body

<p>Android offers a very powerful and yet easy-to-use message type called 
an <a href="{@docRoot}guide/topics/intents/intents-filters.html">intents</a>.
You can use intents to turn applications into high-level libraries and
make code modular and reusable. The Android Home screen and AnyCut 
applications, for instance, use intents extensively to create shortcuts. </p>

<p>While it is nice to be able to make use of a loosely coupled
API, there is no guarantee that the intent you send will be received by
another application. This happens in particular with third-party apps, like 
<a href="http://code.google.com/p/apps-for-android/source/browse/trunk/Panoramio">Panoramio</a> 
and its RADAR intent.</p>

<p>This article describes a technique you can use to find out whether the system
contains any application capable of responding to the intent you want to use.
The example below shows a helper method that queries the system package manager
to determine whether there's an app that can respond to a specified intent. Your
application can pass an intent to the method and then, for example, show or hide
user options that the user would normally use to trigger the intent. </p>

<pre class="prettyprint">/**
 * Indicates whether the specified action can be used as an intent. This
 * method queries the package manager for installed packages that can
 * respond to an intent with the specified action. If no suitable package is
 * found, this method returns false.
 *
 * @param context The application's environment.
 * @param action The Intent action to check for availability.
 *
 * @return True if an Intent with the specified action can be sent and
 *         responded to, false otherwise.
 */
public static boolean isIntentAvailable(Context context, String action) {
    final PackageManager packageManager = context.getPackageManager();
    final Intent intent = new Intent(action);
    List&lt;ResolveInfo&gt; list =
            packageManager.queryIntentActivities(intent,
                    PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() &gt; 0;
}
</pre>

<p>Here is how you could use the helper method:</p>

<pre class="prettyprint">@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    final boolean scanAvailable = isIntentAvailable(this,
        "com.google.zxing.client.android.SCAN");

    MenuItem item;
    item = menu.findItem(R.id.menu_item_add);
    item.setEnabled(scanAvailable);

    return super.onPrepareOptionsMenu(menu);
}
</pre>

<p>In this example, the menu is grayed out if the <em>Barcode Scanner</em> 
application is not installed. </p>

<p>Another, simpler, way to do this is to catch the
<code>ActivityNotFoundException</code> when calling <code>startActivity()</code>
but it only lets you react to the problem, you cannot predict it and update the
UI accordingly to prevent the user from doing something that won't work. The
technique described here can also be used at startup time to ask the user
whether he'd like to install the missing package, you can then simply redirect
him to Google Play by using the appropriate URI.</p>