如何在Android中以编程方式获取当前运行应用的PackageName
Android 获取当前运行应用包名并筛选特定应用
权限配置说明
你已添加的权限需注意版本兼容性:
GET_TASKS:Android 5.0(API 21)已废弃,高版本系统无法通过此方法获取任务列表PACKAGE_USAGE_STATS:仅靠Manifest声明无法自动获取权限,需用户手动到设置 > 安全 > 权限管理 > 应用使用情况中开启QUERY_ALL_PACKAGES:Android 11(API 30)+ 环境下,若需查询所有应用包名需添加此权限;若仅针对WhatsApp、Instagram这类特定应用,可在<queries>标签中声明对应包名,无需此权限<queries>标签:Android 11+ 限制应用可见性,需声明要访问的特定应用包名,示例:
<queries> <package android:name="com.whatsapp" /> <package android:name="com.instagram.android" /> </queries>
可行实现方案
1. 获取前台活跃应用(Android 5.0+ 推荐)
高版本系统中,UsageStatsManager是获取前台应用的可靠方式,替代已废弃的getRunningTasks:
import android.app.usage.UsageStats; import android.app.usage.UsageStatsManager; import android.content.Context; import android.os.Build; import android.text.format.DateUtils; import android.app.AppOpsManager; import android.content.Intent; import android.provider.Settings; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; // 获取前台应用包名 public String getForegroundPackageName(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { // 低版本回退到getRunningTasks(仅兼容至API 20) ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1); return tasks.isEmpty() ? null : tasks.get(0).topActivity.getPackageName(); } else { UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - DateUtils.DAY_IN_MILLIS; // 查询最近1天的使用记录 List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime); if (usageStatsList == null || usageStatsList.isEmpty()) return null; SortedMap<Long, UsageStats> sortedMap = new TreeMap<>(); for (UsageStats stats : usageStatsList) { sortedMap.put(stats.getLastTimeUsed(), stats); } return sortedMap.isEmpty() ? null : sortedMap.get(sortedMap.lastKey()).getPackageName(); } } // 检查是否拥有应用使用统计权限 public boolean hasUsageStatsPermission(Context context) { AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), context.getPackageName()); return mode == AppOpsManager.MODE_ALLOWED; } // 引导用户开启应用使用统计权限 public void requestUsageStatsPermission(Context context) { Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); context.startActivity(intent); }
2. 获取所有运行中的进程(Android 全版本)
getRunningAppProcesses可获取运行进程,但Android 11+ 会限制返回结果,仅能获取自身应用及部分系统进程:
import android.app.ActivityManager; import android.content.Context; import java.util.ArrayList; import java.util.List; // 获取所有运行进程的包名列表 public List<String> getAllRunningPackageNames(Context context) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> runningProcesses = activityManager.getRunningAppProcesses(); List<String> packageNames = new ArrayList<>(); if (runningProcesses != null) { for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) { // 单个进程可能对应多个包名 for (String pkg : processInfo.pkgList) { if (!packageNames.contains(pkg)) { packageNames.add(pkg); } } } } return packageNames; }
3. 筛选特定应用
拿到包名列表后,直接判断目标包名是否存在即可:
import java.util.List; // 判断目标应用是否在运行 public boolean isTargetAppRunning(Context context, String targetPackage) { // 方式1:检查是否为前台应用 String foregroundPkg = getForegroundPackageName(context); if (targetPackage.equals(foregroundPkg)) { return true; } // 方式2:检查是否在运行进程中 List<String> runningPkgs = getAllRunningPackageNames(context); return runningPkgs.contains(targetPackage); } // 使用示例 boolean isWhatsappRunning = isTargetAppRunning(context, "com.whatsapp"); boolean isInstagramRunning = isTargetAppRunning(context, "com.instagram.android");
注意事项
- Android 11+ 应用可见性限制严格,未添加
QUERY_ALL_PACKAGES或在<queries>声明目标包名时,无法查询到对应应用信息 PACKAGE_USAGE_STATS权限必须由用户手动开启,无法通过代码自动请求- 高版本系统中后台进程列表获取受限,优先使用前台应用检测方式判断应用是否活跃
内容的提问来源于stack exchange,提问作者Urvish Stack
相关产品推荐
相关产品推荐

