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
Basic information about Intent resolution
Intents can contain the following basic information:
There are 2 ways that Intents are resolved by the system:
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:
You are creating an implicit Intent and setting the ACTION to "com.something.something". If you then call
startActivity()
with this Intent, you getActivityNotFoundException
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 usingstartActivity()
). To make this work you should eitherCATEGORY="android.intent.category.LAUNCHER"
withCATEGORY="android.intent.category.DEFAULT"
or<category android:name="android.intent.category.DEFAULT" />
to the intent-filter for
SecondActivity
When you do this:
You are creating an explicit Intent specifying the component
SecondActivity
. The signature for this method isIntent(Context packageContext, Class clas)
. It uses the package name frompackageContext
and the class name fromclas
to create an explicit Intent for that component. If you use this constructor inside an Activity, you can just usethis
as the first parameter, becauseActivity
extendsContext
. If you use this constructor from another class (like anOnClickListener
) you need to specifyMyActivity.this
as the first parameter to pass the instance of the Activity and not of the OnClickListener (becauseOnClickListener
does not extendContext
).When you do this:
you are creating an explicit Intent as above. This is exactly the same as using:
You can't do this inside an
OnClickListener
because the first parameter needs to be aContext
(or a class that extendsContext
, likeActivity
).If you want to create an explicit Intent you can also use this:
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: