178

We have installed applications programmatically.

  1. If the application is already installed in the device the application is open automatically.
  2. Otherwise install the particular application.

Guide Me. I have no idea. Thanks.

1

17 Answers 17

346

Try with this:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Add respective layout
        setContentView(R.layout.main_activity);

        // Use package name which we want to check
        boolean isAppInstalled = appInstalledOrNot("com.check.application");  
        
        if(isAppInstalled) {
            //This intent will help you to launch if the package is already installed
            Intent LaunchIntent = getPackageManager()
                .getLaunchIntentForPackage("com.check.application");
            startActivity(LaunchIntent);
                    
            Log.i("SampleLog", "Application is already installed.");          
        } else {
            // Do whatever we want to do if application not installed
            // For example, Redirect to play store

            Log.i("SampleLog", "Application is not currently installed.");
        }
    }

    private boolean appInstalledOrNot(String uri) {
        PackageManager pm = getPackageManager();
        try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
        }

        return false;
    }

}
17
  • 1
    @Sathish: I hope it may helpful for you
    – Aerrow
    Commented Jul 9, 2012 at 9:57
  • 2
    No doubt your post is really helpful , but i am getting a exception "java.lang.RuntimeException: Adding window failed" and " E/AndroidRuntime(7554): Caused by: android.os.TransactionTooLargeException 05-14 11:37:25.305: E/AndroidRuntime(7554): at android.os.BinderProxy.transact(Native Method) 05-14 11:37:25.305: E/AndroidRuntime(7554): at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:516) 05-14 11:37:25.305: E/AndroidRuntime(7554): at android.view.ViewRootImpl.setView(ViewRootImpl.java:494) "
    – DJhon
    Commented May 14, 2014 at 6:16
  • 2
    @BlueGreen: Hi,hope this link may help you, stackoverflow.com/questions/11451393/…, else if you are using Dialog Class means kindly check it. :)
    – Aerrow
    Commented May 14, 2014 at 6:19
  • 1
    @Aerrow.. Suppose i am checking my .apk is installed or nor ? at time of installation... I am getting same exception while checking my package com.test.installedornot.My .apk size is more than 9MB then in that case how i will manage this exception?
    – DJhon
    Commented May 14, 2014 at 6:39
  • 1
    Got crash on API 23 Fatal Exception: java.lang.RuntimeException Package manager has died Commented Aug 9, 2018 at 6:31
78

Somewhat cleaner solution than the accepted answer (based on this question):

public static boolean isAppInstalled(Context context, String packageName) {
    try {
        context.getPackageManager().getApplicationInfo(packageName, 0);
        return true;
    }
    catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

I chose to put it in a helper class as a static utility. Usage example:

boolean whatsappFound = AndroidUtils.isAppInstalled(context, "com.whatsapp");

This answer shows how to get the app from the Play Store if the app is missing, though care needs to be taken on devices that don't have the Play Store.

3
  • 2
    does this require any specific Android permissions to work? Commented Feb 22, 2017 at 14:04
  • @Bootstrapper: No, it doesn't require any special permissions.
    – Jonik
    Commented Feb 22, 2017 at 15:38
  • Thanks (Working Solution) Commented Nov 10, 2017 at 14:56
31

The above code didn't work for me. The following approach worked.

Create an Intent object with appropriate info and then check if the Intent is callable or not using the following function:

private boolean isCallable(Intent intent) {  
        List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,   
        PackageManager.MATCH_DEFAULT_ONLY);  
        return list.size() > 0;  
}
5
  • 5
    This is better because it doesn't require using exceptions for flow control!
    – QED
    Commented Aug 29, 2015 at 22:11
  • 2
    @QED it's appalling the amount of people using Exceptions as if statements! This is definitely the right answer
    – ILikeTacos
    Commented Sep 7, 2015 at 19:44
  • 1
    what's the content of the Intent? the String with the packageName doesn't work Commented Nov 18, 2015 at 17:42
  • 4
    @HenriquedeSousa Intent intent = getPackageManager().getLaunchIntentForPackage("org.package.name");
    – Dominic K
    Commented Jan 5, 2016 at 21:41
  • If the application was disabled, it should be wrong.
    – Hugo
    Commented Jun 14, 2016 at 14:58
18

If you know the package name, then this works without using a try-catch block or iterating through a bunch of packages:

public static boolean isPackageInstalled(Context context, String packageName) {
    final PackageManager packageManager = context.getPackageManager();
    Intent intent = packageManager.getLaunchIntentForPackage(packageName);
    if (intent == null) {
        return false;
    }
    List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return !list.isEmpty();
}
1
  • 1
    return !list.isEmpty(); would be more java style friendly
    – headsvk
    Commented Apr 3, 2017 at 14:37
17

Android 11 update
You have to specify in the manifest the exact bundle id's you want to search for.

Example for facebook and whatsapp:

Inside the Manifest above "application" (where the permissions are)

<queries>
    <package android:name="com.whatsapp" />
    <package android:name="com.facebook.katana" />
</queries>  

This will allow you to check if facebook and whatsapp are installed, otherwise you will always get false for that check.

Further reading on the subject:
https://medium.com/androiddevelopers/package-visibility-in-android-11-cc857f221cd9

0
7

This code checks to make sure the app is installed, but also checks to make sure it's enabled.

private boolean isAppInstalled(String packageName) {
    PackageManager pm = getPackageManager();
    try {
        pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
        return pm.getApplicationInfo(packageName, 0).enabled;
    }
    catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        return false;
    }
}
1
  • It's the package name of the app. For example, "com.example.apps.myapp". I have edited my answer to show packageName instead of uri.
    – caly__pso
    Commented Jul 11, 2016 at 14:30
6

Check App is installed or not in Android by using kotlin.

Creating kotlin extension.

fun PackageManager.isAppInstalled(packageName: String): Boolean = try {
        getApplicationInfo(packageName, PackageManager.GET_META_DATA)
        true
    } catch (e: Exception) {
        false
    }

Now, can check if app is install or not

if (packageManager.isAppInstalled("AppPackageName")) {
    // App is installed
}else{
    // App is not installed
}
4

A simpler implementation using Kotlin

fun PackageManager.isAppInstalled(packageName: String): Boolean =
        getInstalledApplications(PackageManager.GET_META_DATA)
                .firstOrNull { it.packageName == packageName } != null

And call it like this (seeking for Spotify app):

packageManager.isAppInstalled("com.spotify.music")
1
  • As of Android 11, this method no longer returns information about all apps; see g.co/dev/packagevisibility for details
    – Mori
    Commented Sep 28, 2022 at 17:04
4

Cleaner solution (without try-catch) than the accepted answer (based on AndroidRate Library):

public static boolean isPackageExists(@NonNull final Context context, @NonNull final String targetPackage) {
    List<ApplicationInfo> packages = context.getPackageManager().getInstalledApplications(0);
    for (ApplicationInfo packageInfo : packages) {
        if (targetPackage.equals(packageInfo.packageName)) {
            return true;
        }
    }
    return false;
}
3

I think using try/catch pattern is not very well for performance. I advice to use this:

public static boolean appInstalledOrNot(Context context, String uri) {
    PackageManager pm = context.getPackageManager();
    List<PackageInfo> packageInfoList = pm.getInstalledPackages(PackageManager.GET_ACTIVITIES);
    if (packageInfoList != null) {
        for (PackageInfo packageInfo : packageInfoList) {
            String packageName = packageInfo.packageName;
            if (packageName != null && packageName.equals(uri)) {
                return true;
            }
        }
    }
    return false;
}
1
  • The above code in kotlin ``` private fun isAppInstalled(context: Context, uri: String): Boolean { val packageInfoList = context.packageManager.getInstalledPackages(PackageManager.GET_ACTIVITIES) return packageInfoList.asSequence().filter { it?.packageName == uri }.any() } ```
    – Kishan B
    Commented Sep 1, 2017 at 12:42
2

In Kotlin, the simplest way can be two steps

1- in the Manifest put the target app id . ex (com.src.turkey)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <queries>
        <package android:name="com.src.turkey" />
               </queries>
...

2- In an Activity

 try {

 val list = packageManager.getLaunchIntentForPackage("com.src.turkey")
        if (list != null) {
            Log.i("TAG", "downloadApps:$list")
        }

    } catch (e: PackageManager.NameNotFoundException) {
        Log.i("TAG", "downloadApps: False")
    }

There isn't any deprecated such as

queryIntentActivities

pm.getPackageInfo
1
  • 1
    These queries on AndroidManifest is a step that is forgotten by most answers, if you try, for example, the accepted answer without this on a device above Android 11 it won't work.
    – luiscosta
    Commented May 25, 2023 at 11:21
1

Try this

This code is used to check weather your application with package name is installed or not if not then it will open playstore link of your app otherwise your installed app

String your_apppackagename="com.app.testing";
    PackageManager packageManager = getPackageManager();
    ApplicationInfo applicationInfo = null;
    try {
        applicationInfo = packageManager.getApplicationInfo(your_apppackagename, 0);
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    if (applicationInfo == null) {
        // not installed it will open your app directly on playstore
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + your_apppackagename)));
    } else {
        // Installed
        Intent LaunchIntent = packageManager.getLaunchIntentForPackage(your_apppackagename);
        startActivity( LaunchIntent );
    }
1

All the answers only check certain app is installed or not. But, as we all know an app can be installed but disabled by the user, unusable.

Therefore, this solution checks for both. i.e, installed AND enabled apps.

public static boolean isPackageInstalled(String packageName, PackageManager packageManager) {
     try {
          return packageManager.getApplicationInfo(packageName, 0).enabled;
     }
     catch (PackageManager.NameNotFoundException e) {
          return false;
     }
}

Call the method isPackageInstalled():

boolean isAppInstalled = isPackageInstalled("com.android.app" , this.getPackageManager());

Now, use the boolean variable isAppInstalled and do whatever you want.

if(isAppInstalled ) {
    /* do whatever you want */
}
1

You can do it using Kotlin extensions :

fun Context.getInstalledPackages(): List<String> {
    val packagesList = mutableListOf<String>()
    packageManager.getInstalledPackages(0).forEach {
        if ( it.applicationInfo.sourceDir.startsWith("/data/app/") && it.versionName != null)
            packagesList.add(it.packageName)
    }
    return packagesList
}

fun Context.isInDevice(packageName: String): Boolean {
    return getInstalledPackages().contains(packageName)
}
0

@Egemen Hamutçu s answer in kotlin B-)

    private fun isAppInstalled(context: Context, uri: String): Boolean {
        val packageInfoList = context.packageManager.getInstalledPackages(PackageManager.GET_ACTIVITIES)
        return packageInfoList.asSequence().filter { it?.packageName == uri }.any()
    }
0

A cool answer to other problems. If you do not want to differentiate "com.myapp.debug" and "com.myapp.release" for example !

public static boolean isAppInstalled(final Context context, final String packageName) {
    final List<ApplicationInfo> appsInfo = context.getPackageManager().getInstalledApplications(0);
    for (final ApplicationInfo appInfo : appsInfo) {
        if (appInfo.packageName.contains(packageName)) return true;
    }
    return false;
}
0

So nicer with Kotlin suger:

  private fun isSomePackageInstalled(context: Context, packageName: String): Boolean {

    val packageManager = context.packageManager

    return runCatching { packageManager.getPackageInfo(packageName, 0) }.isSuccess
  }

Not the answer you're looking for? Browse other questions tagged or ask your own question.