Android 11+下无需QUERY_ALL_PACKAGES权限获取应用图标与名称的替代方案?
Android 11+ 无需QUERY_ALL_PACKAGES获取应用名称和图标方案
针对你的屏幕时间应用场景,以下是无需申请QUERY_ALL_PACKAGES敏感权限的可行实现方式:
1. 基于PACKAGE_USAGE_STATS权限获取已使用应用的信息
屏幕时间功能本身必须申请PACKAGE_USAGE_STATS权限(用户需在设置中手动开启),借助该权限,你可以通过UsageStatsManager获取用户已使用过的应用包名列表。对于这些包名,直接调用PackageManager的方法即可正常获取应用名称和图标,不会抛出PackageManager.NameNotFoundException:
// 先通过UsageStatsManager获取已使用应用的packageName列表 UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - 7 * 24 * 60 * 60 * 1000; // 示例:最近7天 List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime); // 遍历包名获取应用信息 PackageManager packageManager = getPackageManager(); for (UsageStats stats : usageStatsList) { String packageName = stats.getPackageName(); try { ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0); String appName = packageManager.getApplicationLabel(appInfo).toString(); Drawable appIcon = packageManager.getApplicationIcon(appInfo); // 处理获取到的名称和图标 } catch (PackageManager.NameNotFoundException e) { // 理论上已使用的应用不会走到这里,可做兜底处理(比如显示包名+默认图标) e.printStackTrace(); } }
核心逻辑:PACKAGE_USAGE_STATS权限已赋予你的应用访问用户已使用应用包信息的权限,这类应用不属于“隐藏”范畴,无需额外申请QUERY_ALL_PACKAGES。
2. 兜底处理未使用的应用
对于用户从未使用过的应用,屏幕时间场景下无需统计或展示。如果需要处理这类情况,可直接显示包名+默认应用图标,完全不影响核心功能。
为什么谷歌拒绝你的权限申请
QUERY_ALL_PACKAGES属于敏感权限,仅对应用商店、系统启动器这类确实需要遍历所有应用的场景开放。你的屏幕时间应用只需要关注用户已使用的应用,PACKAGE_USAGE_STATS权限已经足够覆盖需求,这也是谷歌提到的“其他实现方式”的核心。
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

