Thursday, November 3, 2011

Launching an Intent by Action

I had some trouble getting my implicit intent to launch.  An implicit intent is one that uses just the action name string, without specifying the actual class of the action to launch.

This is an explicit Inent:

new Intent(context, com.example.MyActivity.class);


This is an implicit Intent:

new Intent("com.example.my_action");


My app has two different flavors (see earlier post on supporting this), and each one needs to handle a pending intent (in a user Notification) with different Activity classes.  So, the common code, rather than trying to figure out what Activity class to start -- that would be evil indeed, a library having a dependency on its clients -- it specifies an Action in the pending intent, like this:


PendingIntent.getActivity(
    this, -1, new Intent("MY_ACTION")...


Here is the snippet from the manifest:


<activity android:name="com.example.MyActivity" >
  <intent-filter>
        <action android:name="MY_ACTION" /> 
 </intent-filter>

</activity>

Problem was that I would tap on the notification, but nothing would happen.  I finally noticed the following line in LogCat:

WARN/IntentResolver(61): resolveIntent failed: found match, but none with Intent.CATEGORY_DEFAULT

Two things I did wrong.  Both were clearly stated in the documentation, but I missed it.

First, the action name MUST be prefixed with the application package, as declared in the manifest.

Second, the intent-filter element must contain the android.intent.category.DEFAULT category, or else Android will not find your activity to launch. 

So the proper intent filter in the manifest should look like this:


<intent-filter>
  <action android:name="com.example.MY_ACTION" /> 
  <category android:name="android.intent.category.DEFAULT" />

</intent-filter> 


And, of course, the action specified in the Intent constructor should be "com.example.MY_ACTION".

Works great after doing this.

No comments:

Post a Comment