【问题标题】:Check if application is installed - Android检查是否安装了应用程序 - Android
【发布时间】:2013-09-16 03:03:58
【问题描述】:

我正在尝试从 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: 无法启动 活动 组件信息{com.example.appinstaller/com.example.appinstaller.MainActivity}: android.content.ActivityNotFoundException: 未找到处理 Intent { act=android.intent.action.VIEW 的 Activity dat=market://details?id=com.package.name flg=0x40080000 }

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

【问题讨论】:

  • @SiddharthanAsokan 如果我理解正确,你在这里想要实现的是,启动你的应用程序 -> 去玩商店 -> 点击安装 -> 回到你自己的活动 -> 开始新的已安装的应用程序.. 对吗?
  • 不,回到我最初打开的应用程序。我需要使用 PackageManager 获取有关已安装应用程序的一些信息。此信息检索在我从使用打开 Web url 的初始安装应用程序后开始。

标签: android android-intent google-play


【解决方案1】:

试试这个:

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

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

请注意,我们传入的是PackageManager 而不是Context,因此该方法的使用灵活性稍高一些,并且不会违反law of Demeter。只要您有PackageManager 实例,您就可以在不访问Context 实例的情况下使用该方法。

像这样使用它:

public void someMethod() {
    // ...
    
    PackageManager pm = context.getPackageManager();
    boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);
    
    // ...
}

注意:从 Android 11 (API 30) 开始,您可能需要在清单中声明 <queries>,具体取决于您要查找的包。查看the docs 了解更多信息。

【讨论】:

  • 条件是:我需要检查这个安装过程是否完成。我点击安装,同时我尝试循环检查安装。代码很好,但我正在寻找检查安装是否完成的方法。
  • @SiddharthanAsokan 您可以使用广播接收器进行 package_added 操作。
  • @Varun 我刚刚编辑了代码。我不再使用它的应用程序包名称。只是该应用在 Google Play 商店中的网址
  • @Robin Kanters 请检查我所做的更改
  • 强调在清单中添加<queries> 行!
【解决方案2】:

你可以在 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")

【讨论】:

    【解决方案3】:

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

    在此处了解更多信息:

    【讨论】:

    • 注意:根据专门的文档页面,可以默认获取应用本身的applicationInfo。所以应该没有必要将应用程序本身包含在它自己的清单中。
    • @ArpitRastogi 带有一定的限制。您不能将它用于所有类型的应用程序。您的应用必须符合政策。 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
    • @bhavin 仅适用于在 Google Play 商店中发布的应用。如果您不在 Google Play 上,则无需遵守。
    【解决方案4】:

    试试这个:

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

    【讨论】:

      【解决方案5】:

      正在寻找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
              }
          }
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:
          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;
            }
          

          【讨论】:

            【解决方案8】:
                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.");}
            

            【讨论】:

              【解决方案9】:

              更快的解决方案:

              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

              【讨论】:

                【解决方案10】:

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

                【讨论】:

                  【解决方案11】:
                  @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;
                  }
                  

                  【讨论】:

                  • 这是一个无限循环。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-04-02
                  • 2011-10-14
                  • 2014-07-22
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-08-26
                  • 1970-01-01
                  相关资源
                  最近更新 更多