Check if application is installed - Android
Solution 1
Try this:
private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
try {
packageManager.getPackageInfo(packageName, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
It attempts to fetch information about the package whose name you passed in. Failing that, if a NameNotFoundException
was thrown, it means that no package with that name is installed, so we return false
.
Note that we pass in a PackageManager
instead of a Context
, so that the method is slightly more flexibly usable and doesn't violate the law of Demeter. You can use the method without access to a Context
instance, as long as you have a PackageManager
instance.
Use it like this:
public void someMethod() {
// ...
PackageManager pm = context.getPackageManager();
boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);
// ...
}
Note: From Android 11 (API 30), you might need to declare <queries>
in your manifest, depending on what package you're looking for. Check out the docs for more info.
Solution 2
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:
- The migration documentation
- The dedicated documentation page (has more information)
- The official blog post
Solution 3
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())
Solution 4
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
.
Solution 5
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;
}
Comments
-
Siddharthan Asokan almost 3 years
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. -
Siddharthan Asokan almost 11 yearsThe condition is : I need to check this installation process if its done. I click on install and in the mean time i try to check for installation in a loop. The code is fine but the method to check if installation is complete is what im looking for.
-
Varun almost 11 years@SiddharthanAsokan You can use a broadcast receiver for package_added action.
-
Siddharthan Asokan almost 11 years@Varun I just edited the code. Its no more app package name im using. Just the web url of the app in the Google Play Store
-
Siddharthan Asokan almost 11 years@Robin Kanters Please do review the changes i made
-
Robin Kanters almost 11 yearsWhat you did in your question is the same as my answer.
-
code4jhon almost 10 yearshey @RobinKanters is any way to check if the app is installed using the schema name ? e.g. "market://"
-
Robin Kanters almost 9 yearsThis is an infinite loop.
-
Robin Kanters over 8 years@code4jhon according to the documentation, the
market://
URIs are in this format:market://details?id=<package_name>
. So you'd have to trim the first part off and pass the package name to my method above. -
Dimezis about 6 yearsNote that if an app is installed, but disabled in settings, this will also return true, but you won't be able to launch the app. So it will crash on launch
-
Zhou Hongbo over 4 yearsCompared with
getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES)
,isgetPackageInfo(packageName,0)
better? -
BenjyTec over 3 yearsNote: According to the dedicated documentation page, you can get the applicationInfo of the app itself by default. So there should be no need to include the app itself in its own manifest.
-
Arpit about 3 years<queries> <!-- If you don't know apps in advance : --> <package android:name="QUERY_ALL_PACKAGES"/> </queries>
-
Bhavin Patel almost 3 years@ArpitRastogi that comes with certain restriction . You can't use it for all kind of apps . Your app must comply with policy.
Apps granted access to this permission must comply with the User Data policies, including the Prominent Disclosure and Consent requirements, and may not extend its use to undisclosed or invalid purposes.
more information -
ConcernedHobbit over 2 yearsEmphasis on adding the
<queries>
line to your manifest! -
Adam Burley over 2 years@bhavin that is only for apps published on Google Play store. if you aren't on Google Play you don't need to comply with that.