「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 中申明对应权限:
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
以下办法为通过 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<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/…