You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过PackageManager获取Android已安装应用的类别信息?

当然有可行的方法啦!在Android平台上,我们可以借助PackageManager结合系统API或应用元数据来获取应用的类别信息,下面是几种常用且有效的方案:

1. 通过ResolveInfo获取应用声明的Intent类别

当你查询设备上的可启动应用时,ResolveInfo对象里的categories集合会包含该应用在Manifest中声明的类别(比如CATEGORY_LAUNCHERCATEGORY_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_GAMECATEGORY_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_BROWSERIntent.CATEGORY_APP_EMAIL,你可以直接用这些常量来判断应用所属的大类。

内容的提问来源于stack exchange,提问作者Olympus

火山引擎 最新活动