「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中申明对应权限:
<code class="xml"> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions"/>
以下办法为通过 UsageStatsManager 类来获取前台工作包名的具体实现:
<code class="java"> /** * 获取前台利用包名 * * @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<UsageStats> 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/…