Android获取当前运行应用名称问题求助(原方法失效)
获取当前前台运行应用名称的可行方案
你的问题核心是getRunningAppProcesses()在Android 10(API 29)后已废弃,且Android 11+进一步限制了应用获取其他应用运行信息的权限,以下是分版本的合规解决方案:
1. Android 10及以下(API ≤29)
该版本中getRunningAppProcesses()仍可使用,但原代码仅能判断包名存在性,需补充获取应用名称的逻辑:
public static String getForegroundAppName(Context context, String packageName) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses(); if (procInfos != null) { for (ActivityManager.RunningAppProcessInfo processInfo : procInfos) { // 筛选前台进程并匹配包名 if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && processInfo.processName.equals(packageName)) { // 通过包名获取应用显示名称 try { PackageManager pm = context.getPackageManager(); ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0); return pm.getApplicationLabel(appInfo).toString(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return packageName; // 找不到时返回包名兜底 } } } } return ""; }
需在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.GET_TASKS" />
2. Android 11+(API ≥30)
此版本普通应用无法直接获取其他应用进程信息,推荐两种合规方案:
方案A:辅助功能服务(符合隐私规范,推荐)
通过监听界面状态变化获取前台应用包名,进而获取名称:
- 创建辅助服务类:
public class AppBlockAccessibilityService extends AccessibilityService { private String currentForegroundPackage; @Override public void onAccessibilityEvent(AccessibilityEvent event) { // 监听窗口切换事件 if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { currentForegroundPackage = event.getPackageName().toString(); // 获取应用名称并传递给业务逻辑 String appName = getAppName(currentForegroundPackage); // 可通过广播、回调等方式通知AppBlock主逻辑 } } private String getAppName(String packageName) { try { PackageManager pm = getPackageManager(); ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0); return pm.getApplicationLabel(appInfo).toString(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return packageName; } } @Override public void onInterrupt() {} }
- 在
AndroidManifest.xml注册服务:
<service android:name=".AppBlockAccessibilityService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" /> </service>
- 创建
res/xml/accessibility_service_config.xml配置文件:
<?xml version="1.0" encoding="utf-8"?> <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:accessibilityEventTypes="typeWindowStateChanged" android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" android:description="@string/accessibility_service_desc" />
- 在
strings.xml添加权限描述:
<string name="accessibility_service_desc">监控前台应用,实现AppBlock功能</string>
用户需在系统设置中开启该应用的辅助功能权限,即可实时获取前台应用信息。
方案B:使用QUERY_ALL_PACKAGES权限(仅特殊场景使用)
需在AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
通过UsageStatsManager获取应用使用统计来判断前台应用:
public static String getForegroundAppName(Context context) { UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - 60 * 1000; // 查询最近1分钟的使用统计 List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime); if (usageStatsList != null && !usageStatsList.isEmpty()) { UsageStats recentStats = null; // 筛选最近使用的应用 for (UsageStats stats : usageStatsList) { if (recentStats == null || stats.getLastTimeUsed() > recentStats.getLastTimeUsed()) { recentStats = stats; } } if (recentStats != null) { try { PackageManager pm = context.getPackageManager(); ApplicationInfo appInfo = pm.getApplicationInfo(recentStats.getPackageName(), 0); return pm.getApplicationLabel(appInfo).toString(); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return recentStats.getPackageName(); } } } return ""; }
需引导用户授予“使用情况访问权限”,可通过以下代码跳转设置:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); context.startActivity(intent);
关键注意事项
- Android 11+严格限制跨应用信息获取,辅助功能是合规首选方案,
QUERY_ALL_PACKAGES需在Google Play说明用途,否则可能被拒。 - 获取应用名称时必须捕获
PackageManager.NameNotFoundException,避免崩溃。
内容的提问来源于stack exchange,提问作者Matteo Antonuccio
相关产品推荐
相关产品推荐

