25

From one of my apps, I'm trying to launch another. I want to use an explicit intent.

ComponentName cn = new ComponentName("com.myOtherApp", "OtherAppActivity");
Intent intent = new Intent();
intent.setComponent(cn);
context.startActivity(intent);

When I run that code, however, it asks if I've declared that activity in my manifest. However, when I put the following into the manifest, I get the same error:

<activity android:name="com.myOtherApp.OtherAppActivity">
</activity>

What am I doing wrong?

Thanks

Jodes
  • 14,118
  • 26
  • 97
  • 156

6 Answers6

25

Try something like this...

In the manifest for 'myOtherApp' use an intent filter for 'OtherAppActivity' with a company specific intent, example...

<activity
    android:name=".OtherAppActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="com.mycompany.DO_SOMETHING" />
    </intent-filter>
</activity>

Then, in the 'calling' app, use...

Intent intent = new Intent();
intent.setAction("com.mycompany.DO_SOMETHING");
context.startActivity(intent);
Squonk
  • 48,735
  • 19
  • 103
  • 135
22

I had this problem and searched for hours looking for a solution. Finally found it: http://www.krvarma.com/2010/08/launching-external-applications-in-android. That link shows how to use the package manager to launch any application for which you have simply the package name:

PackageManager pm = this.getPackageManager();

try
{
  Intent it = pm.getLaunchIntentForPackage(sName);

  if (null != it)
    this.startActivity(it);
}

catch (ActivityNotFoundException e)
{
}
Jon Vance
  • 504
  • 3
  • 13
18

You need to specify the fully qualified class name in the second parameter of new ComponentName like this:

ComponentName cn = new ComponentName("com.myOtherApp", "com.myOtherApp.OtherAppActivity");

I think this is because the package name in the manifest and the activity name don't necessarily have to have the same package path, so the new ComponentName call doesn't infer the class name second parameter is prefixed by the package name first parameter.

Sogger
  • 15,962
  • 6
  • 43
  • 40
  • Just tested. new ComponentName("com.myOtherApp", ".OtherAppActivity"); doesn't wotk – Wu Yongzheng May 07 '13 at 03:52
  • @WuYongzheng Exactly my point; my answer is that the activity name needs to be a fully qualified path. So your example should be changed to new ComponentName("com.myOtherApp", "com.myOtherApp.OtherAppActivity"); – Sogger May 07 '13 at 14:43
  • your answer and Jon's answer both work. My app got stuck and I realized the incomplete class name bug, so I think it's good to share. The Intent.toString() showing incomplete class name is a bit misleading. – Wu Yongzheng May 08 '13 at 03:22
1

As of API23, you could use the method ComponentName.createRelative(String pkg, String cls) and do:

ComponentName cn = new ComponentName(ComponentName.createRelative("com.myOtherApp", ".OtherAppActivity"));
Intent intent = new Intent();
intent.setComponent(cn);
context.startActivity(intent);

This way you can create a ComponentName object using a relative class path. Mind the dot in the start of the class path. It is necessary to indicate that the method should treat the second argument as a relative path. Just as @Sogger mentioned, the ComponentName constructor constraints the class parameter to be an absolute path.

Note also that by this manner, you are using explicit intents and you don't have to insert any additional intent filters to the destination activity.

pgmank
  • 5,303
  • 5
  • 36
  • 52
0

In addition to @Sogger answer thing to remember is if you receiver class is com.myOtherApp.receiver.OtherAppActivity and package mentioned in AndroidManifest is com.myOtherApp your code will be

ComponentName cn = new ComponentName("com.myOtherApp", "com.myOtherApp.receiver.OtherAppActivity");
aarati
  • 87
  • 8
-2

Create the intent as action.Main and add the launcher category to it:

Intent intent = new Intent("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
Aleadam
  • 40,203
  • 9
  • 86
  • 108