「Android」在后台服务中获取前台任务包名
16lz
2021-12-04
「Android」在后台服务中获取前台任务包名
@wenmingvs 总结了在 Android 里判断 APP 是否处于前台的方法,并把它们整合成了一个工具库 AndroidProcess。
方法 | 判断原理 | 需要权限 | 特点 |
---|---|---|---|
1 | 否 | Android 5.0 以上方法被废弃 | |
2 | 否 | Android 5.1 以上只能获取本进程 | |
3 | UsageStatsService | 是 | 最符合Google规范 |
4 | 通过Android无障碍功能实现 | 是 | 需要用户手动授权 |
5 | 是 | IO操作会引起耗时且Android系统限制 |
经过若干验证,以上方法大多都无法(或存在较多限制)在后台服务中获取前台任务包名。综合比较而言,方法3中通过 UsageStatsManager 类来实现前台任务包名的获取可行性较高。
UsageStatsManager
UsageStatsManager 类为使用情况统计管理者,该类提供了设备使用历史和统计信息,具体数据按天、周、月、年等时间间隔进行聚合。
首先需要在AndroidManifest中声明对应权限:
以下方法为通过 UsageStatsManager 类来获取前台任务包名的具体实现:
/** * 获取前台应用包名 * * @param context 上下文 * @return 前台应用包名 */ public static synchronized String getForegroundPackageName(Context context) { Log.info(true, TAG, "getForegroundPackageName"); String pkgName = Constants.EMPTY_STRING; if (!checkUsageAccessPermission(context)) { // 引导用户打开权限 Log.info(true, TAG, "getForegroundPackageName: no usage access permission"); Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); return Constants.EMPTY_STRING; } long time = System.currentTimeMillis(); long duration = NUMBER_TEN * ONE_MINUTE; long beginTime = time - duration; long endTime = time; Object systemService = context.getSystemService(Context.USAGE_STATS_SERVICE); if (systemService == null) { return Constants.EMPTY_STRING; } if (!(systemService instanceof UsageStatsManager)) { return Constants.EMPTY_STRING; } UsageStatsManager usageStatsManager = (UsageStatsManager) systemService; UsageEvents usageEvents = usageStatsManager.queryEvents(beginTime, endTime); UsageEvents.Event event = new UsageEvents.Event(); while (usageEvents.hasNextEvent()) { usageEvents.getNextEvent(event); if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) { if (TextUtils.equals(context.getPackageName(), event.getPackageName())) { continue; } pkgName = event.getPackageName(); } } Log.info(true, TAG, "pkgName: ", pkgName); return pkgName; } /** * 判断是否具有用户使用情况权限 * * @param context 上下文 * @return 是否具有用户使用情况权限 */ private static boolean checkUsageAccessPermission(Context context) { Log.info(true, TAG, "checkUsageAccessPermission"); Object systemService = context.getSystemService(Context.USAGE_STATS_SERVICE); if (systemService == null) { return false; } if (!(systemService instanceof UsageStatsManager)) { return false; } UsageStatsManager usageStatsManager = (UsageStatsManager) systemService; long time = System.currentTimeMillis(); long duration = NUMBER_TEN * ONE_MINUTE; long beginTime = time - duration; long endTime = time; List usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, beginTime, endTime); return usageStatsList != null && usageStatsList.size() != Constants.DEFAULT_INT_ZERO; }
参考
https://effmx.com/articles/to...
https://github.com/wenmingvs/...
更多相关文章
- 浅谈Java中Collections.sort对List排序的两种方法
- Python list sort方法的具体使用
- python list.sort()根据多个关键字排序的方法实现
- 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Debian镜像
- 史无前例!全网最全的Android面试题集锦(贼干货!)
- Android事件分发机制完全解析(终极版)
- android USB通信
- android 属性android:visibility及 view的setVisibility方法值的
- [Android]实现静默安装APK的两种方法