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

检查应用程序是否已安装-Android,android,android-intent,google-play,Android,Android Intent,Google Play,我正在尝试从Google Play安装应用程序。我可以理解,在打开Google Play商店URL时,它会打开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_

我正在尝试从Google Play安装应用程序。我可以理解,在打开Google Play商店URL时,它会打开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:无法启动 活动 ComponentInfo{com.example.appinstaller/com.example.appinstaller.MainActivity}: android.content.ActivityNotFoundException: 找不到处理Intent{act=android.Intent.action.VIEW的活动 dat=market://details?id=com.package.name flg=0x40080000}

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

请尝试以下操作:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    try {
        packageManager.getPackageInfo(packageName, 0);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}
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;
}
它尝试获取有关您传入其名称的包的信息。否则,如果抛出了
NameNotFoundException
,这意味着没有安装具有该名称的包,因此我们返回
false

请注意,我们传入了一个
PackageManager
,而不是
上下文
,因此该方法的可用性稍有提高,并且不会违反规则。只要您有一个
PackageManager
实例,就可以在不访问
Context
实例的情况下使用该方法

像这样使用它:

public void someMethod() {
    // ...
    
    PackageManager pm = context.getPackageManager();
    boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);
    
    // ...
}
注意:在Android 11(API 30)中,您可能需要在清单中声明
,具体取决于您要查找的软件包。查看更多信息。

尝试以下方法:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
    try {
        packageManager.getPackageInfo(packageName, 0);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        return false;
    }
}
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;
}
公共静态布尔值可用(上下文ctx、意图){
final PackageManager mgr=ctx.getPackageManager();
列表=
经理查询提醒活动(仅适用于意图、PackageManager.MATCH\u默认值);
返回列表.size()>0;
}

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;
    }
}
getPackageGids
getPackageInfo
更便宜,因此工作速度更快

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.");}
//方法来检查安装的包是否正确

  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溶液的人可以使用这种方法

在这里,我共享了完整的代码,还处理了启用状态

自Android 11(API级别30)以来,大多数用户安装的应用程序在默认情况下都不可见。在清单中,您必须静态声明要获取哪些应用的相关信息,如下所示:


...
然后,@RobinKanters的作品:

private boolean isPackageInstalled(字符串packageName、PackageManager PackageManager){
试一试{
packageManager.getPackageInfo(packageName,0);
返回true;
}捕获(PackageManager.NameNotFounde异常){
返回false;
}
}
// ...
//如果安装了应用程序,Android 11上会返回true,
//因为我们在上面的舱单上声明了。
iPackageInstalled(“com.example.this.app”,pm);
//即使安装了应用程序,在Android 11上也会返回false:
iPackageInstalled(“另一个.random.app”,pm);
在此处了解更多信息:


您可以在Kotlin
extensions.kt中使用此选项

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


可能重复@SiddharthanAsokan如果我理解正确,您在这里试图实现的是,启动您的应用程序->转到游戏商店->单击安装->返回您自己的活动->启动新安装的应用程序。。是吗?不,回到我最初打开的应用程序。我需要使用PackageManager获取有关已安装应用程序的一些信息。此信息检索在我从用于打开web url的初始应用程序安装应用程序后开始。条件是:如果安装完成,我需要检查此安装过程。我单击install,同时尝试在循环中检查安装情况。代码很好,但检查安装是否完成的方法是我要找的。@SiddharthanAsokan您可以使用广播接收器来执行程序包添加的操作。@Varun我刚刚编辑了代码。我不再使用它的应用程序包名称。只需谷歌Play中应用程序的web urlStore@RobinKanters请查看我所做的更改。您在问题中所做的与我的答案相同。这是一个无限循环。注意:根据专用文档页面,默认情况下,您可以获取应用程序本身的应用程序信息。因此,不需要将应用程序本身包含在自己的清单中。
fun Context.isPackageInstalled(packageName: String): Boolean {
    return try {
        packageManager.getPackageInfo(packageName, 0)
        true
    } catch (e: PackageManager.NameNotFoundException) {
        false
    }
}
context.isPackageInstalled("com.somepackage.name")