如何判断Android应用处于前台/后台?解决Service导致的误判问题
问题分析
你遇到的核心问题是:isAppRunning方法同时检查了应用的任务栈(Activity)和后台服务(Service),而你的Service本身就一直在后台运行,所以无论应用界面是否关闭,这个方法都会返回true,导致无法触发启动应用的逻辑。
你的真实需求是判断应用的可见界面(Activity)是否处于运行状态,而非后台Service是否存在,因此只需要调整判断逻辑即可。
解决方案1:简化判断逻辑(兼容旧版本)
直接修改isAppRunning方法,去掉对后台Service的检查,只保留任务栈中Activity的判断:
public static boolean isAppActivityRunning(final String pkgName) { ActivityManager am = (ActivityManager) Utils.getApp().getSystemService(Context.ACTIVITY_SERVICE); if (am != null) { List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(Integer.MAX_VALUE); if (taskInfo != null && taskInfo.size() > 0) { for (ActivityManager.RunningTaskInfo aInfo : taskInfo) { if (aInfo.baseActivity != null && pkgName.equals(aInfo.baseActivity.getPackageName())) { return true; } } } } return false; }
然后在充电监听回调中替换方法调用:
@Override public void onBatteryStatusChanged(BatteryUtils.Status status) { if (status.getStatus() == BatteryUtils.BatteryStatus.CHARGING) { if(!AppUtils.isAppActivityRunning(getPackageName())) LogUtils.dTag(Constants.TAG, "APP SHOULD LAUNCH NOW"); } }
解决方案2:适配Android 5.0+(推荐)
getRunningTasks在Android 5.0(API 21)后已被废弃,若需兼容更高版本系统,可使用UsageStatsManager判断应用是否处于前台:
- 先在
AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
- 编写前台判断方法:
public static boolean isAppForeground(String pkgName) { UsageStatsManager usageStatsManager = (UsageStatsManager) Utils.getApp().getSystemService(Context.USAGE_STATS_SERVICE); long endTime = System.currentTimeMillis(); long startTime = endTime - 1000 * 60; // 检查最近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; } } return recentStats != null && pkgName.equals(recentStats.getPackageName()); } return false; }
- 替换监听回调中的方法调用即可。
内容的提问来源于stack exchange,提问作者user7954210
相关产品推荐
相关产品推荐

