578

I want to launch an installed package from my Android application. I assume that it is possible using intents, but I didn't find a way of doing it. Is there a link, where to find the information?

2
  • 2
    what happen if I open second app from first one and then click directly the icon of second app, I get two instances of the app, which is undesired.how to manage it ?? Commented Nov 21, 2014 at 14:44
  • Possible duplicate of How to call one android application from another android application Commented Nov 17, 2015 at 10:18

19 Answers 19

793

If you don't know the main activity, then the package name can be used to launch the application.

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
if (launchIntent != null) { 
    startActivity(launchIntent);//null pointer check in case package name was not found
}
Sign up to request clarification or add additional context in comments.

13 Comments

Any reason as to why this would not work? I didn't get it to work at least.
It starts a new Intent , how about resuming the application which is in background?
@andep: This worked well for me when I tested between two apps i created myself. Once I know the package name will this always work, or is there a way to prevent someone from launching your app (in the maniefest or somewhere)?
@Leonard: My first impression, that it must always work, because package names are public so any apps can read them out. From your apps I think you cannot determine from where was it called but your app can determines that it can not be call via the main activity just via services.
For android version 10+ you also need to add <queries> tag in AndroidManifest.xml file otherwise getLaunchIntentForPackage() will return null i.e. <queries> <package android:name="OtherApplicationID" /> </queries>
|
274

I know this has been answered but here is how I implemented something similar:

Intent intent = getPackageManager().getLaunchIntentForPackage("com.package.name");
if (intent != null) {
    // We found the activity now start the activity
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
} else {
    // Bring user to the market or let them choose an app?
    intent = new Intent(Intent.ACTION_VIEW);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setData(Uri.parse("market://details?id=" + "com.package.name"));
    startActivity(intent);
}

Even better, here is the method:

public void startNewActivity(Context context, String packageName) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    if (intent != null) {
        // We found the activity now start the activity
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    } else {
        // Bring user to the market or let them choose an app?
        intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setData(Uri.parse("market://details?id=" + packageName));
        context.startActivity(intent);
    }
}

Removed duplicate code:

public void startNewActivity(Context context, String packageName) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    if (intent == null) {
        // Bring user to the market or let them choose an app?
        intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("market://details?id=" + packageName));
    }
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
}

7 Comments

I was having an issue when starting an Intent to a Facebook or Twitter profile. They were opening inside my app, instead of as a new activity. Adding the FLAG_ACTIVITY_NEW_TASK fixed that. Thanks!
No problem! I was having trouble with something very similiar
The method works for me, but sometimes the new Application is open and the calling Activity is still the foreground. Any ideas how to fix?
Is there any way to do this from instant-app?
Works only for release versions. If you're trying to open the debug app, intent will be null.
|
175

I found the solution. In the manifest file of the application I found the package name: com.package.address and the name of the main activity which I want to launch: MainActivity The following code starts this application:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);

7 Comments

i got exception ' dose you declare activity in your Manifest.xml'
This way returns an exception which says I need to declare the activity in my manifest.. but its an external app!
How to run it in background? Means second called applications doesn't show on screen, but run its onCreated() method.
I get this error when i try from instant app: Not allowed to start activity Intent
@Bastian how to close the current app from where we call intent to open another app?
|
22

Add the packages inside AndroidManifest.xml file, which you want to use:

<manifest
............
    <queries>
        <package android:name="com.google.android.gm" />
        ........
    </queries>
</manifest>

Updated

fun Context.isAppAvailable(packageName: String): Boolean {
    var appStatus = false
    try {
        val ai = if (isFromAPI(33)) {
            packageManager.getApplicationInfo(
                packageName, PackageManager.ApplicationInfoFlags.of(0)
            )
        } else {
            packageManager.getApplicationInfo(packageName, 0)
        }
        appStatus = ai.enabled
    } catch (e: PackageManager.NameNotFoundException) {
        e.printStackTrace()
    }
    return appStatus
}

Old - Java

// in onCreate method
String appName = "Gmail";
String packageName = "com.google.android.gm";
openApp(context, appName, packageName);

public static void openApp(Context context, String appName, String packageName) {
    if (isAppInstalled(context, packageName))
        if (isAppEnabled(context, packageName))
            context.startActivity(context.getPackageManager().getLaunchIntentForPackage(packageName));
        else Toast.makeText(context, appName + " app is not enabled.", Toast.LENGTH_SHORT).show();
    else Toast.makeText(context, appName + " app is not installed.", Toast.LENGTH_SHORT).show();
}

private static boolean isAppInstalled(Context context, String packageName) {
    PackageManager pm = context.getPackageManager();
    try {
        pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
        return true;
    } catch (PackageManager.NameNotFoundException ignored) {
    }
    return false;
}

private static boolean isAppEnabled(Context context, String packageName) {
    boolean appStatus = false;
    try {
        ApplicationInfo ai = context.getPackageManager().getApplicationInfo(packageName, 0);
        if (ai != null) {
            appStatus = ai.enabled;
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    return appStatus;
}

2 Comments

The two methods to check the install and enabled status of the app are really commendable. Most others skipped them. However, I'd like to know if isAppInstalled() can be written without throwing NameNotFoundException. I cross-checked other posts and sites, but they are mostly the same code as here. So, is it possible to do it while not throwing the exception?
This exception will occur when the package is not installed into your phone.
20

Edit depending on comment

In some versions - as suggested in comments - the exception thrown may be different.

Thus the solution below is slightly modified

Intent launchIntent = null;
try{
   launchIntent = getPackageManager().getLaunchIntentForPackage("applicationId");
} catch (Exception ignored) {}

if(launchIntent == null){
    startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")));
} else {
    startActivity(launchIntent);
}

Original Answer

Although answered well, there is a pretty simple implementation that handles if the app is not installed. I do it like this

try{
    startActivity(getPackageManager().getLaunchIntentForPackage("applicationId"));
} catch (PackageManager.NameNotFoundException e) {
    startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")));
}

Replace "applicationId" with the package that you want to open such as com.google.maps, etc.

5 Comments

The PackageManager.getLaunchIntentForPackage(...) method returns null if the package name is not recognised. It does not throw PackageManager.NameNotFoundException. See here.
I just tried startActivity(null) on an Android 10 emulator and it throws a NullPointerException and not a PackageManager.NameNotFoundException.
On my note 7 it works exactly the way it is intended.
What is the intended behaviour of the startActivity(Intent intent) method when it is given a null Intent and what makes you say that? The Android developers' documentation only states that it will throw an ActivityNotFoundException.
Also you need to add <package android:name="applicationId" /> under <queries> section in AndroidManifest file if you are targetting Android 11 or more (or else getLaunchIntentForPackage will return null . For more details - developer.android.com/training/package-visibility
17

Here is my example of launching bar/QR code scanner from my app if someone finds it useful

Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.setPackage("com.google.zxing.client.android");

try 
{
    startActivityForResult(intent, SCAN_REQUEST_CODE);
} 
catch (ActivityNotFoundException e) 
{
    //implement prompt dialog asking user to download the package
    AlertDialog.Builder downloadDialog = new AlertDialog.Builder(this);
    downloadDialog.setTitle(stringTitle);
    downloadDialog.setMessage(stringMessage);
    downloadDialog.setPositiveButton("yes",
            new DialogInterface.OnClickListener() 
            {
                public void onClick(DialogInterface dialogInterface, int i) 
                {
                    Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
                    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                    try
                    {
                        myActivity.this.startActivity(intent);
                    }
                    catch (ActivityNotFoundException e)
                    {
                        Dialogs.this.showAlert("ERROR", "Google Play Market not found!");
                    }
                }
            });
    downloadDialog.setNegativeButton("no",
            new DialogInterface.OnClickListener() 
            {
                public void onClick(DialogInterface dialog, int i) 
                {
                    dialog.dismiss();
                }
            });
    downloadDialog.show();
}

Comments

15

Starting from API 30 (Android 11) you can receive nullpointerexception with launchIntentForPackage

val launchIntent: Intent? = activity.packageManager.getLaunchIntentForPackage("com.google.android.gm")
startActivity(launchIntent) 

To avoid this you need to add the needed package to the manifest

<queries>
    <package android:name="com.google.android.gm" />
</queries>

Here is documentation https://developer.android.com/training/package-visibility

And the medium article https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9

3 Comments

Why does google keep breaking shit? What if your app legitimately needs to dynamically start applications?
@TheRealChx101 you should use QUERY_ALL_PACKAGES in that case
Yeah but in this case, you need to prove to Google that your app really needs this
9

Check for the app, avoiding any crashes. If the app exists in the phone then it will be launched, otherwise it will search in Google Play. If no Google Play app installed in the phone, it will search in the Google Play Store via browser:

public void onLunchAnotherApp() {
    final String appPackageName = getApplicationContext().getPackageName();

    Intent intent = getPackageManager().getLaunchIntentForPackage(appPackageName);
    if (intent != null) {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    } else {
        onGoToAnotherInAppStore(intent, appPackageName);
    }
}

public void onGoToAnotherInAppStore(Intent intent, String appPackageName) {
    try {
        intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setData(Uri.parse("market://details?id=" + appPackageName));
        startActivity(intent);
    } catch (android.content.ActivityNotFoundException anfe) {
        intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setData(Uri.parse("http://play.google.com/store/apps/details?id=" + appPackageName));
        startActivity(intent);
    }
}

1 Comment

is there a character limit to the uri.parse method?
8

If you want to open specific activity of another application we can use this.

Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try 
{
    startActivity(intent)
}catch(ActivityNotFoundException e){
    Toast.makeText(context,"Activity Not Found",Toast.LENGTH_SHORT).show()
}

If you must need other application, instead of showing Toast you can show a dialog. Using dialog you can bring the user to Play-Store to download required application.

1 Comment

com.android.settings.fuelgauge.PowerUsageSummary is just an activity-alias of com.android.settings.Settings$PowerUsageSummaryActivity, and it was removed in Android Pie, so I summitted the edit to make this answer suit Pie. Note that it's also compatible with older version, see AOSP commit on Nov 10, 2011 af9252849fd94c1f2859c56a4010900ea38a607e etc
6

It is possible to start an app's activity by using Intent.setClassName according to the docs.

An example:

val activityName = "com.google.android.apps.muzei.MuzeiActivity" // target activity name
val packageName = "net.nurik.roman.muzei" // target package's name
val intent = Intent().setClassName(packageName, activityName)
startActivity(intent)

To open it outside the current app, add this flag before starting the intent.

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

A related answer here

2 Comments

pls how to write in C++.
@GeneCode stackoverflow.com/a/22436147/8608146 might help I never worked with c++ libs in android before.
4

This will cover all scenarios

1.Get intent for package

2.If intent is null redirect user to playstore

3.If there is an issue with open playstore, then it opens on the default browser.

var intent = activity!!.packageManager.getLaunchIntentForPackage("com.google.android.youtube")

          if (intent == null) {
            if (intent == null) {
                    intent = try {
                        Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.youtube"))
                    } catch (e: Exception) {
                        Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.google.android.youtube"))
                    }
                }
             startActivity(intent)

For Android 11 (API level 30) or higher, in AndroidManifest.xml,

<queries>
    <package android:name="com.google.android.youtube" />
    <package android:name="com.example.app" />
</queries>

Or simply we can allow for all packages (not recommended)

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />

References

Package visibility filtering on Android

Declaring package visibility needs

Comments

2

If you know the data and the action the installed package react on, you simply should add these information to your intent instance before starting it.

If you have access to the AndroidManifest of the other app, you can see all needed information there.

5 Comments

Thanks for the reply. Yes I have the AndroidManifest of the other application. What I try to do now is the following code: Intent intent = new Intent(Intent.ACTION_MAIN); intent.setComponent(new ComponentName("com.package",".MainActivity")); startActivity(intent); but in this way it is not working. Can you give me a more precise link, how to do it?
The application crashes at the line "startActivity...": The application has stopped unexpectedly. Pleas try again. Where can I see the error in LogCat?
I found the error: When setting the component, the fully qualified class name instead of just the class has to be named: intent.setComponent(new ComponentName("com.package","com.package.MainActivity")) instead of intent.setComponent(new ComponentName("com.package",".MainActivity"))
Good to know... You can find the LogCat on eclipse: Window > Show view > Other, Android > Logcat
@WarrenFaith I need support with stackoverflow.com/questions/52335402/… Please help.
2

Steps to launch new activity as follows:

1.Get intent for package

2.If intent is null redirect user to playstore

3.If intent is not null open activity

public void launchNewActivity(Context context, String packageName) {
    Intent intent = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.CUPCAKE) {
        intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    }
    if (intent == null) {
        try {
            intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("market://details?id=" + packageName));
            context.startActivity(intent);
        } catch (android.content.ActivityNotFoundException anfe) {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + packageName)));
        }
    } else {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
}

Comments

2
private fun openOtherApp() {
        val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
        startActivity(sendIntent)
        finishAffinity()
    }

Comments

2

Pass the package name and the message you want to show if package isn't installed ;-)

void openApp(String appPackageName,String message){
    Intent launchIntent = getPackageManager().getLaunchIntentForPackage(appPackageName);
    if (launchIntent != null) {
        startActivity(launchIntent);
    } else {
        Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + appPackageName)));
    }
}

Comments

1

Try code below:

Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("package_name", "Class_name"));
if (intent.resolveActivity(getPackageManager()) != null) 
{
   startActivity(intent);
}

Comments

1

In Kotlin

fun openApplicationOrMarket(packageName: String) {
        var intent = requireContext().packageManager.getLaunchIntentForPackage(packageName)
        if (intent == null) {
            intent = Intent(Intent.ACTION_VIEW)
            intent.data = Uri.parse("market://details?id=$packageName")
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        requireContext().startActivity(intent)
    }

Comments

1

I may be late for the party, but this could help someone.
Add the launcher with the required package name and update the AndroidManifest.xml file

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.other.app.id");
if (launchIntent != null) { 
    startActivity(launchIntent);
}

For Android version 10 and above, you must add the <queries> tag in the AndroidManifest.xml file (Outside of the Application tag). Otherwise getLaunchIntentForPackage() will return null

<queries> <package android:name="com.other.app.id" /> </queries>

Comments

0

Since kotlin is becoming very popular these days, I think it's appropriate to provide a simple solution in Kotlin as well.

var launchIntent: Intent? = null
try {
    launchIntent = packageManager.getLaunchIntentForPackage("applicationId")
} catch (ignored: Exception) {
}
if (launchIntent == null) {
    startActivity(Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://play.google.com/store/apps/details?id=" + "applicationId")))
} else {
    startActivity(launchIntent)
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.