[android] Check if application is installed - Android

I'm trying to install apps from Google Play. I can understand that on opening the Google Play store URL, it opens the Google Play and when I press the back button, the activity resumes.

Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(appURL));
marketIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(marketIntent);

When I went back to the activity, I tried calling this onResume() to check if the app is installed, but I receive an error:

@Override
protected void onResume() {
    super.onResume();
    boolean installed = false;
    while (!installed) {
        installed  =   appInstalledOrNot(APPPACKAGE);
        if (installed) {
             Toast.makeText(this, "App installed", Toast.LENGTH_SHORT).show();
        }
    }
}

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

The error is as follows:

E/AndroidRuntime(796): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.appinstaller/com.example.appinstaller.MainActivity}: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=market://details?id=com.package.name flg=0x40080000 }

I guess the activity is onPause(). Is there a better way to implement it? I'm trying to check if the app has finished installing.

This question is related to android android-intent google-play

The answer is


Faster solution:

private boolean isPackageInstalled(String packagename, PackageManager packageManager) {
    try {
        packageManager.getPackageGids(packagename);
        return true;
    } catch (NameNotFoundException e) {
        return false;
    }
}

getPackageGids is less expensive from getPackageInfo, so it work faster.

Run 10000 on API 15
Exists pkg:
getPackageInfo: nanoTime = 930000000
getPackageGids: nanoTime = 350000000
Not exists pkg:
getPackageInfo: nanoTime = 420000000
getPackageGids: nanoTime = 380000000

Run 10000 on API 17
Exists pkg:
getPackageInfo: nanoTime = 2942745517
getPackageGids: nanoTime = 2443716170
Not exists pkg:
getPackageInfo: nanoTime = 2467565849
getPackageGids: nanoTime = 2479833890

Run 10000 on API 22
Exists pkg:
getPackageInfo: nanoTime = 4596551615
getPackageGids: nanoTime = 1864970154
Not exists pkg:
getPackageInfo: nanoTime = 3830033616
getPackageGids: nanoTime = 3789230769

Run 10000 on API 25
Exists pkg:
getPackageInfo: nanoTime = 3436647394
getPackageGids: nanoTime = 2876970397
Not exists pkg:
getPackageInfo: nanoTime = 3252946114
getPackageGids: nanoTime = 3117544269

Note: This will not work in some virtual spaces. They can violate the Android API and always return an array, even if there is no application with that package name.
In this case, use getPackageInfo.


You can use this in Kotlin extentions.kt

fun Context.isPackageInstalled(packageName: String): Boolean {
    return try {
        packageManager.getPackageInfo(packageName, 0)
        true
    } catch (e: PackageManager.NameNotFoundException) {
        false
    }
}

Usage

context.isPackageInstalled("com.somepackage.name")

Those who are looking for Kotlin solution can use this method,

Here I have shared full code, and also handled enabled status. Check If Application is Installed in Android Kotlin

fun isAppInstalled(packageName: String, context: Context): Boolean {
        return try {
            val packageManager = context.packageManager
            packageManager.getPackageInfo(packageName, 0)
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }
    }

If you want to try it without the try catch block, can use the following method, Create a intent and set the package of the app which you want to verify

val intent = Intent(Intent.ACTION_VIEW)
intent.data = uri
intent.setPackage("com.example.packageofapp")

and the call the following method to check if the app is installed

fun isInstalled(intent:Intent) :Boolean{
    val list = context.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
    return list.isNotEmpty()
}

    private boolean isAppExist() {

    PackageManager pm = getPackageManager();
    try {
        PackageInfo info = pm.getPackageInfo("com.facebook.katana", PackageManager.GET_META_DATA);
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
    return true;
}




if (isFacebookExist()) {showToast(" Facebook is  install.");}
     else {showToast(" Facebook is not install.");}

Robin Kanters' answer is right, but it does check for installed apps regardless of their enabled or disabled state.

We all know an app can be installed but disabled by the user, therefore unusable.

This checks for 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;
    }
}

You can put this method in a class like Utils and call it everywhere using:

boolean isInstalled = Utils.isPackageInstalled("com.package.name", context.getPackageManager())

isFakeGPSInstalled = Utils.isPackageInstalled(Utils.PACKAGE_ID_FAKE_GPS, this.getPackageManager());

//method to check package installed true/false

  public static boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    boolean found = true;
    try {
      packageManager.getPackageInfo(packageName, 0);
    } catch (PackageManager.NameNotFoundException e) {
      found = false;
    }

    return found;
  }

Try this:

public static boolean isAvailable(Context ctx, Intent intent) {
    final PackageManager mgr = ctx.getPackageManager();
    List<ResolveInfo> list =
        mgr.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

@Override 
protected void onResume() {
    super.onResume();
    boolean installed = false;

    while (!installed) {
        installed = appInstalledOrNot (APPPACKAGE);
        if (installed) {
            Toast.makeText(this, "App installed", Toast.LENGTH_SHORT).show ();
        }
    }
} 

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

Since Android 11 (API level 30), most user-installed apps are not visible by default. In your manifest, you must statically declare which apps you are going to get info about, as in the following:

<manifest>
    <queries>
        <!-- Explicit apps you know in advance about: -->
        <package android:name="com.example.this.app"/>
        <package android:name="com.example.this.other.app"/>
    </queries>
    
    ...
</manifest>

Then, @RobinKanters' answer works:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    try {
        packageManager.getPackageInfo(packageName, 0);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}

// ...
// This will return true on Android 11 if the app is installed,
// since we declared it above in the manifest.
isPackageInstalled("com.example.this.app", pm); 
// This will return false on Android 11 even if the app is installed:
isPackageInstalled("another.random.app", pm); 

Learn more here:


Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to android-intent

Kotlin Android start new Activity Open Facebook Page in Facebook App (if installed) on Android Android - Adding at least one Activity with an ACTION-VIEW intent-filter after Updating SDK version 23 Not an enclosing class error Android Studio Parcelable encountered IOException writing serializable object getactivity() Sending intent to BroadcastReceiver from adb How to pass ArrayList<CustomeObject> from one activity to another? Android Intent Cannot resolve constructor Android Gallery on Android 4.4 (KitKat) returns different URI for Intent.ACTION_GET_CONTENT Android - java.lang.SecurityException: Permission Denial: starting Intent

Examples related to google-play

How to enable Google Play App Signing google console error `OR-IEH-01` Is Google Play Store supported in avd emulators? updating Google play services in Emulator How to change package name in android studio? How to change Android version and code version number? Check if application is installed - Android Where do alpha testers download Google Play Android apps? Is it possible to change the package name of an Android app on Google Play? "Insufficient Storage Available" even there is lot of free space in device memory