检查是否安装了应用程序-Android

我正在尝试从 Google Play 安装应用程序。我可以理解,打开谷歌播放商店的网址,它打开谷歌播放,当我按下后退按钮,活动恢复。

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);

当我返回到这个活动时,我尝试调用这个 onResume()来检查应用程序是否已经安装,但是我收到一个错误:

@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 ;
}

错误如下:

E/AndroidRuntime (796) : java.lang. RuntimeException: 无法启动 活动 组件信息{ com.example.appinstaller/com.example.appinstaller. MainActivity } : 异常: 没有找到处理意图{ act = android.Intent.action.VIEW 的活动 Dat = market://Details? id = com.package.name flg = 0x40080000}

我猜测活动是 onPause()。有没有更好的方法来实现它?我正在检查应用程序是否已经安装完毕。

165450 次浏览

试试这个:

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

注意!

来自 Android 11(API 30) ,您可能需要在清单中声明 <queries>,这取决于你想要的软件包。更多信息请查看 那些文件

工作原理:

它尝试获取有关您传入名称的包的信息。否则,如果抛出 NameNotFoundException,则意味着没有安装该名称的包,因此我们返回 false

请注意,我们传入的是 PackageManager而不是 Context,因此该方法的可用性稍微更灵活一些,并且不违反 得墨忒耳律法。只要有一个 PackageManager实例,就可以在不访问 Context实例的情况下使用该方法。

使用方法:

public void someMethod() {
// ...
    

PackageManager pm = context.getPackageManager();
boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);
    

// ...
}

试试这个:

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;
}

Robin Kanters 的回答是正确的,但它确实会检查已安装的应用程序,而不管它们处于启用或禁用状态。

我们都知道一个应用程序可以被安装,但是被用户禁用,因此不能使用。

这将检查已安装的启用 还有的应用程序:

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

您可以将这个方法放到类 Utils中,并使用以下方法在任何地方调用它:

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

更快的解决方案:

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

getPackageGidsgetPackageInfo便宜,所以它工作得更快。

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

注意: 这在某些虚拟空间中不起作用。它们可以违反 Android API,并且总是返回一个数组,即使没有包名称的应用程序。
在这种情况下,使用 getPackageInfo

    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.");}
isFakeGPSInstalled = Utils.isPackageInstalled(Utils.PACKAGE_ID_FAKE_GPS, this.getPackageManager());

//方法检查安装的包 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 catch 块的情况下尝试它,可以使用以下方法, 创建一个意图并设置要验证的应用程序包

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

并调用以下方法来检查应用程序是否已安装

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

寻找 Kotlin 解决方案的人可以使用这种方法,

这里我已经共享了完整的代码,并且处理了启用状态

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

自从安卓11(API 等级30)以来,大多数用户安装的应用程序在默认情况下是不可见的。在您的清单中,您必须静态声明您将获得哪些应用程序的信息,如下所示:

<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>

然后,@RobinKanters 的 回答工作:

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);

你可在此了解更多资料:

你可以在 Kotlin 使用这个

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

用法

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

安卓11之后,您需要在应用程序清单中的 <queries>中添加包名称。

如果在清单中没有 <queries>,总是 context.getPackageManager().getApplicationInfo有一个异常(Err: android.content.pm . PackageManager $NamenotFoundException)

检查参考: 链接

例如:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">


<queries>
<package android:name="com.xxx.yyy" />
</queries>


<application></application>


</manifest>

爪哇咖啡

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

Koltin

fun applicationIsInstall(context: Context, packageName: String): Boolean {
return try {
context.packageManager.getApplicationInfo(packageName, 0)
true
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
false
}
}