How to launch an Activity from another Application in Android
Asked Answered
K

19

567

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?

Koser answered 6/10, 2010 at 11:46 Comment(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 ??Scrutator
Possible duplicate of How to call one android application from another android applicationXeroderma
J
787

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
}
Jenine answered 27/9, 2011 at 19:36 Comment(13)
Any reason as to why this would not work? I didn't get it to work at least.Quarter
It starts a new Intent , how about resuming the application which is in background?Gerlachovka
@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)?Enright
@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.Jenine
Yes, this can return null. "The current implementation looks first for a main activity in the category CATEGORY_INFO, and next for a main activity in the category CATEGORY_LAUNCHER. Returns null if neither are found."Raasch
what if I wanted to open a Facebook app from my android application(Which I've designed). Because I dont the package used by Facebook at this time what I'm supposed to do??Lully
This not works in Instant app. how can handle it in Instant apps?Armagnac
what if I want to launch a specific activity of the other app?Sophister
Works only if the other app is release version. Debug apps aren't found this way.Entrust
@Jenine - how to close the present app(activity) when we call another app.Loleta
@ArnoldBrown Call finish(); to close the activity.Windhover
This worked for me. However, if you are a rookie (like me), you need to know how to get the package name of the app to be launched. i.e. find the android sdk location and use the adb command to list the package names of the installed apps.Gentlewoman
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>Domiciliate
D
272

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);
}
Dingman answered 17/3, 2013 at 20:25 Comment(7)
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!Commit
No problem! I was having trouble with something very similiarDingman
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?Herewith
Is there any way to do this from instant-app?Armagnac
Works only for release versions. If you're trying to open the debug app, intent will be null.Entrust
@JaredBurrows what to do id the called app has not installed? How to inform users to install that app?Loleta
can this work when starting other apps Broadcast Receiver ?Echols
K
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);
Koser answered 6/10, 2010 at 14:1 Comment(7)
i got exception ' dose you declare activity in your Manifest.xml'Edgy
This way returns an exception which says I need to declare the activity in my manifest.. but its an external app!Colloquy
How to run it in background? Means second called applications doesn't show on screen, but run its onCreated() method.Northington
I get this error when i try from instant app: Not allowed to start activity IntentArmagnac
@Koser how to close the current app from where we call intent to open another app?Loleta
this is the best solution which worked for me because getLaunchIntentForPackage returns null for some apps.Formaldehyde
Using new ComponentName("com.package.address","com.package.address.MainActivity") and NOT new ComponentName("com.package.address",".MainActivity") results in -> Error: context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you wantNorthington
C
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.

Cerulean answered 2/12, 2018 at 4:22 Comment(5)
The PackageManager.getLaunchIntentForPackage(...) method returns null if the package name is not recognised. It does not throw PackageManager.NameNotFoundException. See here.Dandiprat
I just tried startActivity(null) on an Android 10 emulator and it throws a NullPointerException and not a PackageManager.NameNotFoundException.Dandiprat
On my note 7 it works exactly the way it is intended.Cerulean
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.Dandiprat
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-visibilityKalmia
W
19
// 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;
}
Winch answered 12/10, 2017 at 9:6 Comment(0)
U
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();
}
Uralaltaic answered 9/8, 2013 at 8:50 Comment(0)
O
10

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

Okra answered 17/11, 2021 at 22:11 Comment(4)
Exactly, thanks.Narcotism
Why does google keep breaking shit? What if your app legitimately needs to dynamically start applications?Mollymollycoddle
@Mollymollycoddle you should use QUERY_ALL_PACKAGES in that caseLocomobile
Yeah but in this case, you need to prove to Google that your app really needs thisOkra
H
8

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);
    }
}
Haught answered 24/6, 2015 at 10:56 Comment(1)
is there a character limit to the uri.parse method?Sapsago
E
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.

Endermic answered 23/12, 2017 at 3:53 Comment(1)
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 etcElspeth
C
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

Chavey answered 3/12, 2019 at 11:27 Comment(2)
pls how to write in C++.Plat
@Plat https://mcmap.net/q/74395/-call-android-activity-from-jni-directly-from-c-process-without-java-side might help I never worked with c++ libs in android before.Chavey
A
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

Allergist answered 19/12, 2021 at 4:15 Comment(0)
C
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.

Cylinder answered 6/10, 2010 at 11:50 Comment(5)
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?Koser
The application crashes at the line "startActivity...": The application has stopped unexpectedly. Pleas try again. Where can I see the error in LogCat?Koser
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"))Koser
Good to know... You can find the LogCat on eclipse: Window > Show view > Other, Android > LogcatCylinder
@Cylinder I need support with #52335902 Please help.Eartha
I
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);
    }
}
Intracardiac answered 5/9, 2017 at 5:15 Comment(0)
B
2
private fun openOtherApp() {
        val sendIntent = packageManager.getLaunchIntentForPackage("org.mab.dhyanaqrscanner")
        startActivity(sendIntent)
        finishAffinity()
    }
Bunkmate answered 19/11, 2019 at 10:27 Comment(0)
R
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)));
    }
}
Romanticist answered 26/9, 2021 at 21:3 Comment(0)
D
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);
}
Diogenes answered 6/1, 2021 at 11:41 Comment(0)
T
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)
    }
Tennyson answered 8/6, 2021 at 14:33 Comment(0)
C
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)
}
Cerulean answered 30/1, 2021 at 16:21 Comment(0)
F
0

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>

Fleenor answered 22/1 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.