【问题标题】:How to get the list of apps that have been installed by a user on an Android device?如何获取用户在 Android 设备上安装的应用程序列表?
【发布时间】:2011-06-03 16:22:10
【问题描述】:

我目前正在使用以下代码:

List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);

但它返回已由设备制造商和我安装的应用程序。如何限制它只返回我安装的应用程序?

【问题讨论】:

标签: android android-package-managers android-applicationinfo installed-applications


【解决方案1】:
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final List pkgAppsList = context.getPackageManager().queryIntentActivities( mainIntent, 0);

【讨论】:

  • 如果我执行 pkgAppsList.get(0),它会返回一个 ResolveInfo 对象。如何获取图标、包名等信息?
【解决方案2】:
// Flags: See below
int flags = PackageManager.GET_META_DATA | 
            PackageManager.GET_SHARED_LIBRARY_FILES |     
            PackageManager.GET_UNINSTALLED_PACKAGES;

PackageManager pm = getPackageManager();
List<ApplicationInfo> applications = pm.getInstalledApplications(flags);
for (ApplicationInfo appInfo : applications) {
    if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
        // System application
    } else {
        // Installed by user
    }
}

标志:

【讨论】:

  • getInstalledApplications(0) 中的 0 代表什么。 doco 没有说明 int 0。developer.android.com/reference/android/test/mock/…
  • 您的 if 条件不正确。它应该是 applications.get(n).applicationInfo.flags :)
  • @Raunak - 我的 if 条件是正确的。在手机上试试,你会看到的。另外,试试你的建议,你会发现它不能编译。
  • @GSree - 同意。文档没有明确提到 0,尽管它有效并且意味着所有应用程序。或者,我可以使用 PackageManager.GET_UNINSTALLED_PACKAGES 而不是 0。我用它来遵循问题本身描述的原始方法。
  • 我已经修正了这个例子!
【解决方案3】:

如果我执行 pkgAppsList.get(0),它会返回一个 ResolveInfo 对象。如何获取图标、包名等信息?

这样做:

ResolveInfo info = pkgAppsList.get(0);
ApplicationInfo appInfo = info.activityInfo.applicationInfo;

PackageManager packageManager = = getPackageManager();
//And then you retrieve all needed data:
Drawable packageIcon = packageManager.getApplicationIcon(applicationInfo); //Icon
String packageName = applicationInfo.packageName; //Package name
String packageLabel = String.valueOf(packageManager.getApplicationLabel(applicationInfo)) //Package label(app name)

【讨论】:

    【解决方案4】:

    Zelimir 的回答是正确的。但在某些情况下,它不会为您提供所有已安装的第三方应用程序。 ApplicationInfo 还设置了标志 FLAG_UPDATED_SYSTEM_APP

    如果此应用程序已作为内置系统的更新安装 应用

    在我的智能手机上,此类应用程序包括 Amazone Kindle、Adobe Reader、Slacker Radio 等。这些应用程序不是手机附带的,而是从 Google Play 商店安装的。因此,它们可以被视为第三方应用程序。

    因此,您可能还想检查FLAG_UPDATED_SYSTEM_APP 标志。

    final PackageManager packageManager = _context.getPackageManager();
    List<ApplicationInfo> installedApplications = 
        packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
    
    for (ApplicationInfo appInfo : installedApplications)
    {
        if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)
        {
            // IS A SYSTEM APP
        }
    
        if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)
        {
            // APP WAS INSTALL AS AN UPDATE TO A BUILD-IN SYSTEM APP
        }
    }
    

    【讨论】:

      【解决方案5】:

      用户

      1. pkgAppsList.get(i).activityInfo.packageName 获取 packageName
      2. pkgAppsList.get(i).activityInfo.applicationInfo.loadLabel(getPackageManager()).toString()fetch app level name

      【讨论】:

        【解决方案6】:

        Nikolai 的回答是正确的,但可以使用迭代器进行优化。这是我想出的:

        /**
         * Return list of installed user applications
         */
        static List<ApplicationInfo> getUserInstalledApplications(Context context) {
            // Get installed applications
            final PackageManager packageManager = context.getPackageManager();
            List<ApplicationInfo> installedApplications =
                    packageManager.getInstalledApplications(PackageManager.GET_META_DATA);
        
            // Remove system apps
            Iterator<ApplicationInfo> it = installedApplications.iterator();
            while (it.hasNext()) {
                ApplicationInfo appInfo = it.next();
                if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                    it.remove();
                }
            }
        
            // Return installed applications
            return installedApplications;
        }
        

        【讨论】:

          【解决方案7】:

          Android PackageManager 类用于检索有关当前安装在设备上的应用程序包的信息。您可以通过调用 getPackageManager() 获取 PackageManager 类的实例。 PackageManager 提供了查询和操作已安装包和相关权限等方法。在这个 Android 示例中,我们获取了 Android 中已安装应用的列表。

          PackageManager packageManager = getPackageManager(); 列表列表 = packageManager.getInstalledApplications(PackageManager.GET_META_DATA)

          packageManager.getInstalledApplications() 返回设备上安装的所有应用程序包的列表。如果我们设置标志 GET_UNINSTALLED_PACKAGES 已设置,则将返回所有应用程序的列表,包括使用 DONT_DELETE_DATA 删除的应用程序(部分安装的应用程序具有数据目录)。

          完整信息here.

          又一个好read here.

          【讨论】:

            【解决方案8】:

            为 android 11/API 30 回答这个问题

            context.getPackageManager().getInstalledApplications(PackageManager.GET_META_DATA); 上述代码返回系统应用列表,因为用户应用默认不可见,您需要在清单中添加以下权限以获取用户应用列表

            &lt;uses-permission android:name"android.permission.QUERY_ALL_PACKAGES"&gt;

            【讨论】:

            • “GET_META_DATA”与系统应用无关。即使使用 0 作为参数,您仍然会得到这些。
            【解决方案9】:

            如果您想知道如何在 Kotlin 中执行此操作,如下所示,但正如 Ketan sangle 之前提到的,您需要在 AndroidManifest.xml 文件中添加 &lt;uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission"/&gt;

            val packages = packageManager.getInstalledApplications(PackageManager.GET_META_DATA)
            
            for (packageInfo in packages) {
                        if (packageInfo.flags and ApplicationInfo.FLAG_SYSTEM != 1) {
                             //enter what you want to do here
                        }
                    }
            

            在这种情况下,我使用系统标志来排除系统应用程序,您可以找到其他标志here

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-05
              相关资源
              最近更新 更多