android5.1应用打开次数统计(优化篇)

前一段时间写过有关统计文章,具体分析了系统原理和使用方法,但是使用过程中又碰到了统计不精确的问题,具体来说就是过滤方式导致的。之前的方式是获取当前包名的第一个classname作为key,但是在事件列表中可能会出现统计作为key的classname只出现一次而以后每次统计都没有该class参与,这就导致这个统计的应用次数出错。

不太清楚的请参考之前文章
http://blog.csdn.net/elder_sword/article/details/50809642
http://blog.csdn.net/elder_sword/article/details/50809941

使用当前方式可以做到的最终效果是,可以每次实时的获取到手机应用打开次数的情况(这里的打开的概念是应用到桌面就算一次打开),但是需要用户手动打开手机设置中”有权限使用情况的应用”对应的应用权限,想要后台偷偷的统计,除了是系统应用去默认打开权限或是直接在源码上做改动,其它方式暂时没想到有可以实现的方案,如果有希望能联系我

废话不多说直接上代码

/**
 * 只查询当天的应用打开事件
 * @throws NoSuchFieldException
 */
public static void printEvents() throws NoSuchFieldException {

    long endTime = System.currentTimeMillis();
    long startTime = DateUtil.getTimesmorning();
    Log.d(TAG_U, "Range start:" + dateFormat.format(startTime));
    Log.d(TAG_U, "Range end:" + dateFormat.format(endTime));

    UsageEvents events = mUsmManager.queryEvents(startTime, endTime);
    if(eventList!=null){
        eventList.clear();
    }
    eventList = new ArrayList();
    while (events.hasNextEvent()) {
        UsageEvents.Event e = new UsageEvents.Event();
        events.getNextEvent(e);
        StatisticsEvent event = null;
        if (e != null && e.getEventType() == 1) {
            event = new StatisticsEvent();
            event.setClazz(e.getClassName());
            event.setPkgname(e.getPackageName());
            event.setLasttime(e.getTimeStamp());
            event.setType(e.getEventType());
            eventList.add(event);
            Log.d(TAG_U, "Event:----lasttime = " + DateUtils.formatSameDayTime(e.getTimeStamp(), System.currentTimeMillis(), DateFormat.MEDIUM, DateFormat.MEDIUM)
                    + "---- pkgname = " + e.getPackageName()
                    + "----class = " + e.getClassName()
                    + "----type =" + e.getEventType());
        }
    }
    printEventsMine();
}

上面主要是把今天所有的应用打开事件列表获取出来为后面进行过滤做准备

/**
 * 对查询出来所有的事件进行过滤
 * @throws NoSuchFieldException
 */
public static void printEventsMine() throws NoSuchFieldException {
    HashMap pkgNames = new HashMap();
    if(mPkgs!=null){
        mPkgs.clear();
    }
    mPkgs = new HashMap();
    for(int i=0;i//判断所有事件中当前如果为launcher时去判断上一个事件,上一个事件不是launcher就手动添加到mPkgs,并且打开次数+1
        if(packageName.contains("launcher")&&i>0){
            StatisticsEvent e1 = eventList.get(i-1);
            String pkgname = e1.getPkgname();
            if(!pkgname.contains("launcher")){
                    e1.setCount(mPkgs.get(pkgname)==null?1:mPkgs.get(pkgname).getCount() + 1);
                    mPkgs.put(pkgname, e1);
                    Log.d(TAG,"Event:-"+e1.getPkgname()+"count"+e1.getCount());
                }
        }

        //如果为最后一个事件,不是launcher就做上面相同的操作
        if(i==eventList.size()-1){
            if(!packageName.contains("launcher")){
                e.setCount(mPkgs.get(packageName)==null?1:mPkgs.get(packageName).getCount() + 1);
                mPkgs.put(packageName, e);
                Log.d(TAG,"last  Event:-"+e.getPkgname()+"count"+e.getCount());
            }
        }
    }
}

统计的方案就是注释里所说的,执行完这个方法,当天过滤后的应用打开信息就在mPkgs里了,剩余的就是去遍历map,按照个人所需的业务去做了。

其实网上有个叫24PI的应用他们是专门来统计这个,在5.0以上,这个应用第一次进入也需要去勾选权限,曾经反编译但是没有找到类似的做法的代码,很可能能是其它方式实现的,值得思考。

下载代码

你可能感兴趣的:(android应用,android系统)