「Android」在后台服务中获取前台任务包名

@wenmingvs 总结了在 Android 里判断 APP 是否处于前台的方法,并把它们整合成了一个工具库 AndroidProcess。

方法 判断原理 需要权限 特点
1 RunningTask Android 5.0 以上方法被废弃
2 RunningProcess Android 5.1 以上只能获取本进程
3 UsageStatsService 最符合Google规范
4 通过Android无障碍功能实现 需要用户手动授权
5 读取/proc目录下的信息 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/...

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Debian镜像
  5. 史无前例!全网最全的Android面试题集锦(贼干货!)
  6. Android事件分发机制完全解析(终极版)
  7. android USB通信
  8. android 属性android:visibility及 view的setVisibility方法值的
  9. [Android]实现静默安装APK的两种方法

随机推荐

  1. android toast用法总结(一)
  2. Json数据解析
  3. MyAdapter
  4. Nexus刷官方下载的映像_occam
  5. android Home键 屏蔽,捕获,修改
  6. 【Android】TypedArray——三个方法获取d
  7. Android(安卓)Arrayadapter 获得数据方法
  8. Android(安卓)采用Lame编码器编码mp3文件
  9. Android(安卓)Studio gradle生成jar
  10. android bitmap out of memory总结、心得