Android应用统计-使用时长及次数统计(一)

关键字: 应用统计 Android源码 应用使用时长 应用使用次数

最近在做有关于应用统计有关的工作,主要是统计系统中客户端应用(非系统自带的那些基础应用,比如DownLoadManager),在每一天的使用情况,统计内容包括:应用打开次数,应用合计使用时长等。
在所搜寻的方案中,大致有如下两种:

  • 方案一:自行记录每次activity的打开和关闭,根据这些数据进行统计。
  • 方案二:使用系统自行记录的每次activity的打开和关闭数据,进行统计。

以下方案采用两个方案并行,主要是以系统数据统计结果为主,以自行记录的数据作为参照,用以对比两组数据,以保证数据统计结果的有效性和稳定性。

系统数据

在Android中,系统会自行记录应用的打开次数和使用时间,且提供了相关api于开发者,但是每一次版本提升都可能会对api带来相当大的改变,这一块也不例外。但是始终没有变化的就是在拨号键盘输入* # * #4636# * #*,进入工程模式,点击“使用情况统计数据”,你就可以看到统计界面了。由于各个版本之间差异比较大,而且相关的资料也比较少,本次使用的api以及相关的说明都是以Android-5.1为基础。在某些版本中,应用统计api,存在不少缺陷以及避坑的地方,尤其是手机厂家修改过源码之后,所以对于某些品牌的测试机器,程序的运行结果会有一点不一样,请各位读者有所注意。

如何获取系统数据

第一步:获取权限

  1. 在manifest文件中注册该权限
    <permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
  2. 在系统setting应用中打开相应开关,准许demo应用获取数据。如果不执行这一步的话,demo将无法读取系统数据。
    测试机 : 小米4C。
    打开目录 : 设置 -〉其他高级设置 -〉安全和隐私 -〉有权查看使用情况的应用。界面如下图:


第二步:获取数据

  1. 获取系统统计信息:
       @SuppressWarnings("ResourceType")
       @TargetApi(Build.VERSION_CODES.LOLLIPOP)
       public static ArrayList<UsageStats> getUsageList(Context context, long startTime, long endTime) {
  
        Log.i(TAG," EventUtils-getUsageList()   Range start:" + startTime);
        Log.i(TAG," EventUtils-getUsageList()   Range end:" + endTime);
        Log.i(TAG," EventUtils-getUsageList()   Range start:" + dateFormat.format(startTime));
        Log.i(TAG," EventUtils-getUsageList()   Range end:" + dateFormat.format(endTime));

        ArrayList<UsageStats> list = new ArrayList<>();

        UsageStatsManager mUsmManager = (UsageStatsManager) context.getSystemService("usagestats");
        Map<String, UsageStats> map = mUsmManager.queryAndAggregateUsageStats(startTime, endTime);
        for (Map.Entry<String, UsageStats> entry : map.entrySet()) {
            UsageStats stats = entry.getValue();
            if(stats.getTotalTimeInForeground() > 0){
                list.add(stats);
                Log.i(TAG," EventUtils-getUsageList()   stats:" + stats.getPackageName() + "   TotalTimeInForeground = " + stats.getTotalTimeInForeground());
            }
        }

        return list;
        }
  1. 获取系统记录的详细的各个activity的使用情况:
    @SuppressWarnings("ResourceType")
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static ArrayList<UsageEvents.Event> getEventList(Context context, long startTime, long endTime){
        ArrayList<UsageEvents.Event> mEventList = new ArrayList<>();

        Log.i(TAG," EventUtils-getEventList()   Range start:" + startTime);
        Log.i(TAG," EventUtils-getEventList()   Range end:" +endTime);
        Log.i(TAG," EventUtils-getEventList()   Range start:" + dateFormat.format(startTime));
        Log.i(TAG," EventUtils-getEventList()   Range end:" + dateFormat.format(endTime));

        UsageStatsManager mUsmManager = (UsageStatsManager) context.getSystemService("usagestats");
        UsageEvents events = mUsmManager.queryEvents(startTime, endTime);

        while (events.hasNextEvent()) {
            UsageEvents.Event e = new UsageEvents.Event();
            events.getNextEvent(e);
            if (e != null && (e.getEventType() == 1 || e.getEventType() == 2)) {
                Log.i(TAG," EventUtils-getEventList()  "+e.getTimeStamp()+"   event:" + e.getClassName() + "   type = " + e.getEventType());
                mEventList.add(e);
            }
        }

        return mEventList;
    }
  1. 获取系统记录的各个应用的使用次数:
    由于该字段不能通过api拿到,故而采取反射的形式,拿到该字段。(注:其实该字段的统计数据并不可靠,一旦强行关机,比如拔电池,就可能失去数据,所以在系统代码中该字段是被隐藏的。当然关于数据的可靠性,在接下来的文章中会有更详细的说明)
private int getLaunchCount(UsageStats usageStats) throws IllegalAccessException {
        Field field = null;
        try {
            field = usageStats.getClass().getDeclaredField("mLaunchCount");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return (int) field.get(usageStats);
    }

结语:

本文主要介绍了关于Android系统中统计各个app的使用情况的解决方案,以及获取相关数据的方法。关于系统记录的数据的原理以及在该原理的逻辑下可能出现的bug,将会在接下来的文章中详细阐述。

转载请注明出处。

github:UseTimeStatistic
参考文献:
Android 5.0以上通过UsageStatsManager类 获取应用使用情况(精品)
android如何获取系统里各个应用的使用时间?
Android UsageStatsService:要点解析
Android5.1应用打开次数获取

下一篇:Android应用统计-使用时长及次数统计(二)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,930评论 25 708
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,853评论 18 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,096评论 6 13
  • 知本来就是一种建构意识形态的行动,所以起心动念都是行!一念发动处即是行了。行本身就是一种价值观的落实和体现,这样的...
    0818ba15cc2b阅读 155评论 0 0
  • 设计模式の行为型模式(1) 我们经历了创建型模式,结构型模式,最终来到了设计模式的终点站:行为型模式. 以下我们讲...
    tinysnake阅读 478评论 0 0