如何通过PackageManager获取Android已安装应用的类别信息?
当然有可行的方法啦!在Android平台上,我们可以借助PackageManager结合系统API或应用元数据来获取应用的类别信息,下面是几种常用且有效的方案:
1. 通过ResolveInfo获取应用声明的Intent类别
当你查询设备上的可启动应用时,ResolveInfo对象里的categories集合会包含该应用在Manifest中声明的类别(比如CATEGORY_LAUNCHER、CATEGORY_APP_MUSIC这类系统预定义的类别)。示例代码如下:
PackageManager pm = getPackageManager(); Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); List<ResolveInfo> appList = pm.queryIntentActivities(mainIntent, 0); for (ResolveInfo info : appList) { Set<String> categories = info.filter.categories; // 遍历集合获取所有声明的类别 for (String category : categories) { Log.d("AppCategory", String.format("%s : %s", info.activityInfo.packageName, category)); } }
不过要注意,这种方法只能拿到应用主动声明的类别,有些应用可能没添加太多类别声明,结果会比较有限。
2. 利用Android 11+新增的getApplicationCategory()方法
从Android 11(API 30)开始,PackageManager提供了getApplicationCategory()方法,能直接返回系统为应用分配的官方类别(比如CATEGORY_GAME、CATEGORY_SOCIAL等),这个类别是系统根据应用功能自动判定的,准确性更高。示例代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { PackageManager pm = getPackageManager(); try { // 获取类别对应的int常量 int categoryCode = pm.getApplicationCategory("com.example.targetapp"); // 转换为可读的类别名称 String categoryName = pm.getApplicationCategoryName(categoryCode); Log.d("AppCategory", categoryName); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } }
局限性很明显:只能在API 30及以上的设备使用,低版本系统无法调用。
3. 读取应用自定义元数据中的类别
部分应用开发者会在Manifest的<application>标签里添加自定义元数据来标注应用类别,比如:
<application ...> <meta-data android:name="APP_CATEGORY" android:value="E-commerce" /> </application>
我们可以通过PackageManager读取这些自定义元数据:
PackageManager pm = getPackageManager(); try { ApplicationInfo appInfo = pm.getApplicationInfo("com.example.targetapp", PackageManager.GET_META_DATA); if (appInfo.metaData != null) { String customCategory = appInfo.metaData.getString("APP_CATEGORY"); if (customCategory != null) { Log.d("AppCategory", customCategory); } } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); }
但这种方法完全依赖开发者是否主动添加了元数据,通用性不强,适合针对特定应用的场景。
额外注意事项
- 在Android 11及以上系统中,如果你需要查询所有已安装应用的信息,需要在Manifest中申请
QUERY_ALL_PACKAGES权限;如果只是针对特定应用,可以通过指定包名来避免申请全权限。 - 系统预定义的类别常量都在
Intent类中,比如Intent.CATEGORY_APP_BROWSER、Intent.CATEGORY_APP_EMAIL,你可以直接用这些常量来判断应用所属的大类。
内容的提问来源于stack exchange,提问作者Olympus




