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

时间:2013-09-11 22:15:44

标签: android android-intent google-play

我正在尝试从Google Play安装应用。我可以理解,在打开Goog​​le Play商店网址时,它会打开Goog​​le 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()。有没有更好的方法来实现它?我正在尝试检查应用是否已完成安装。

11 个答案:

答案 0 :(得分:246)

试试这个:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {

    boolean found = true;

    try {

        packageManager.getPackageInfo(packageName, 0);
    } catch (PackageManager.NameNotFoundException e) {

        found = false;
    }

    return found;
}

它尝试获取有关您传入其名称的包的信息。如果失败,如果抛出NameNotFoundException,则表示没有安装具有该名称的包,因此我们返回false

请注意,我们传入了PackageManager而不是Context,因此该方法可以更灵活地使用,并且不会违反law of Demeter。只要您拥有Context实例,就可以使用该方法无法访问PackageManager实例。

像这样使用:

public void someMethod() {
    // ...

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

    // ...
}

答案 1 :(得分:17)

Robin Kanters的答案是正确的,但它确实检查已安装的应用程序,无论其启用或禁用状态如何。

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

这会检查已安装的 AND 启用的应用:

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

答案 2 :(得分:7)

从Android 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的answer起作用:

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

在此处了解更多信息:

答案 3 :(得分:5)

试试这个:

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

答案 4 :(得分:4)

更快的解决方案:

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

答案 5 :(得分:0)

    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.");}

答案 6 :(得分:0)

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

//检查安装的软件包是否正确的方法

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

    return found;
  }

答案 7 :(得分:0)

如果您想在没有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()
}

答案 8 :(得分:0)

正在寻找Kotlin解决方案的人可以使用此方法,

在这里,我共享了完整的代码,并且还处理了启用状态。 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
        }
    }

答案 9 :(得分:0)

您可以在Kotlin extentions.kt中使用它

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

用法

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

答案 10 :(得分:-8)

getDuration