Android intent syntax

android, android-intent, syntax

Solution

Basic information about Intent resolution

Intents can contain the following basic information:

- ACTION

- CATEGORY

- DATA

- COMPONENT

There are 2 ways that Intents are resolved by the system:

- Explicit (uses COMPONENT if it is specified)

- Implicit (uses ACTION, CATEGORY and DATA to find suitable activity)

If you specify the component (package name and class name) then this is used to explicitly find the activity you have specified and the Intent is sent to that activity. The other Intent data is not used (although it is passed to the called activity in the Intent). This is called "explicit Intent resolution".

If you don't specify the component, then the ACTION, CATEGORY and DATA fields are used to locate one or more activities that advertise (via intent-filter) that they can accept the Intent. This is called "implicit Intent resolution".

To your specific questions

When you do this:

Intent in = new Intent("com.something.something");

You are creating an implicit Intent and setting the ACTION to "com.something.something". If you then call `startActivity()` with this Intent, you get `ActivityNotFoundException` because Android cannot find an activity that can accept an Intent with ACTION="com.something.something". The reason is because you have provided an intent-filter with ACTION="com.something.something" and CATEGORY="android.intent.category.LAUNCHER" but you haven't specified the CATEGORY in your Intent (Android automatically adds the CATEGORY "DEFAULT" to an Intent if there isn't any CATEGORY specified when using `startActivity()`). To make this work you should either

- Replace `CATEGORY="android.intent.category.LAUNCHER"` with `CATEGORY="android.intent.category.DEFAULT"` or

- Add `<category android:name="android.intent.category.DEFAULT" />`

to the intent-filter for `SecondActivity`

When you do this:

Intent in = new Intent(MainActivity.this, SecondActivity.class);

You are creating an explicit Intent specifying the component `SecondActivity`. The signature for this method is `Intent(Context packageContext, Class clas)`. It uses the package name from `packageContext` and the class name from `clas` to create an explicit Intent for that component. If you use this constructor inside an Activity, you can just use `this` as the first parameter, because `Activity` extends `Context`. If you use this constructor from another class (like an `OnClickListener`) you need to specify `MyActivity.this` as the first parameter to pass the instance of the Activity and not of the OnClickListener (because `OnClickListener` does not extend `Context`).

When you do this:

Intent in = new Intent().setClass(this, SecondActivity.class);

you are creating an explicit Intent as above. This is exactly the same as using:

Intent in = new Intent(this, SecondActivity.class);

You can't do this inside an `OnClickListener` because the first parameter needs to be a `Context` (or a class that extends `Context`, like `Activity`).

If you want to create an explicit Intent you can also use this:

Intent in = new Intent().setClassName("com.something", "com.something.SecondActivity");

This creates an explicit intent, but you don't need a `Context` for this. You can just pass the package name and the class name as Strings (if you know them).

For more information about Intent resolution, see:

- http://developer.android.com/guide/components/intents-filters.html

- http://developer.android.com/reference/android/content/Intent.html

- http://developer.android.com/reference/android/content/IntentFilter.html

Problem

In my attempts to find out how to start a new intent in my app, I've come across several ways of phrasing it. This syntax returns a runtime error, namely a ActivityNotFound exception ``` Intent in = new Intent("com.something.something"); ``` Of course my android manifest contains an action within the intent filter: ``` <activity android:name=".SecondActivity" android:label="@string/title_activity_second" > <intent-filter> <action android:name="com.something.something" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> ``` This formatting works: ``` Intent in = new Intent(MainActivity.this, SecondActivity.class); ``` I also tried the following: ``` Intent in = new Intent(this, SomeActivity.class); ``` that was recommended in a book I'm reading. This returns a runtime error, activitynotfound This one makes Eclipse throw me back and forth between setClass and setClassName infinitely: ``` Intent in = new Intent().setClass(this, SecondActivity.class); ``` I'm using it in an onclick method: ``` ok.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent in = new Intent(MainActivity.this, SecondActivity.class); startActivity(in); } }); } ``` What's the difference between these and why is only one of them working for me? Regards /M

Original source