android判断点击次数_Android应用统计-使用时长及次数统计(一)

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

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

在所搜寻的方案中,大致有如下两种:

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

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

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

系统数据

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

如何获取系统数据

第一步:获取权限

在manifest文件中注册该权限

在系统setting应用中打开相应开关,准许demo应用获取数据。如果不执行这一步的话,demo将无法读取系统数据。

测试机 : 小米4C。

打开目录 : 设置 -〉其他高级设置 -〉安全和隐私 -〉有权查看使用情况的应用。界面如下图:

第二步:获取数据

获取系统统计信息:

@SuppressWarnings("ResourceType")

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

public static ArrayList 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 list = new ArrayList<>();

UsageStatsManager mUsmManager = (UsageStatsManager) context.getSystemService("usagestats");

Map map = mUsmManager.queryAndAggregateUsageStats(startTime, endTime);

for (Map.Entry 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;

}

获取系统记录的详细的各个activity的使用情况:

@SuppressWarnings("ResourceType")

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

public static ArrayList getEventList(Context context, long startTime, long endTime){

ArrayList 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;

}

获取系统记录的各个应用的使用次数:

由于该字段不能通过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,将会在接下来的文章中详细阐述。

转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux+cp+-rdf,简单构建基于RDF和SPARQL的KBQA(知识图谱问答系统)

本文主要通过python实例讲解基于RDF和SPARQL的KBQA系统的构建。该项目可在python2和python3上运行通过。注&#xff1a;KBQA即是我们通常所说的基于知识图谱的问答系统。这里简单构建的EasyKBQA&#xff0c;数据来源于网络&#xff0c;源码地址看下面补充说明。目录&#xff1a…

java中Object.equals()简单用法

/* equals&#xff08;&#xff09;方法默认的比较两个对象的引用&#xff01; */ class Child {int num;public Child(int x){num x;}//人文的抛出运行时异常的好处是&#xff1a;可以自定义错误信息&#xff01;/*public boolean equals(Object o) throws ClassCastExceptio…

cmd imp导入dmp文件_oracle导入dmp文件的2种方法

使用imp、impdp方式导入数据1.使用imp导入数据打开cmd窗口&#xff0c;然后直接敲入一下命令即可&#xff0c;需要注意的是&#xff0c;要事先把dmp文件放到正确的路径中去imp yx_base/yx_192. file E:\yxb\yx_base.dmp log E:\yxb\yx_base.log full y2.使用impdp导入数据(1…

from server sql 拼接统计两个子查询_[SQL SERVER系列]之嵌套子查询和相关子查询

子查询有两种类型&#xff0c;一种是只返回一个单值的子查询&#xff0c;这时它可以用在一个单值可以使用的地方&#xff0c;这时子查询可以看作是一个拥有返回值的函数&#xff1b;另外一种是返回一列值的子查询&#xff0c;这时子查询可以看作是一个在内存中临时存在的数据表…

java中包容易出现的错误及权限问题

/* 3&#xff0c;权限在不同地方的体现&#xff1a; public protected default private 同一类中&#xff1a; ok ok ok ok 同一包中&#xff1a; ok ok ok 子类中&#xff1a; ok ok …

c语言程序算一元二次方程,如何用C语言来计算一元二次方程

C语言实现一元二次方程的解 源程序#include#includefloat x1,x2,p,q,d;float great_than_zero(float,float);float equql_to_zero(float,float);float smaller_than_zero(float,float);main(){float a,b,c;printf(“Enter a,b,c:”);scanf(“%f%f%f”,&a,&b,&c);db…

cosin等于多少_cos45度等于多少

cos45度√2/2。角A的邻边比斜边叫做角A的余弦&#xff0c;记作cosA(由余弦英文cosine简写得来)&#xff0c;即cosA等于角A的邻边/斜边(直角三角形)。二倍角公式sin2α2sinαcosαtan2α2tanα/(1-tan^2(α))cos2αcos^2(α)-sin^2(α)2cos^2(α)-11-2sin^2(α)积化和差公式sinα…

c语言宏定义比较三个数大小,C语言中两个宏进行大小对比,其中一个没有定义,这种行为如何定义。...

1.C语言中两个宏进行大小对比&#xff0c;其中一个没有定义&#xff0c;这种行为如何定义呢&#xff1f;在学习U-boot的过程中遇到这么一个定义&#xff1a;# if (CONFIG_ENV_ADDR > CONFIG_SYS_MONITOR_BASE) && \(CONFIG_ENV_ADDR CONFIG_ENV_SIZE) < \(CONFI…

java中变量运算细节 (2)

/* 目的&#xff1a;测试变量的运算方式 结果&#xff1a;byte a, b, c;a bc;或者 a b10形如这种形式的算式&#xff0c; 等式的右边的运算结果默认的都是int型的&#xff01;因为等式右边有变量&#xff0c; 编译器无法确定变量的内容&#xff0c;因为它是变量&#xff01;所…

c语言设计二级考试程序修改题,全国计算机二级考试C语言复习题与答案解析

全国计算机二级考试C语言复习题与答案解析三、程序修改题下列给定程序中函数fun的功能是&#xff1a;将长整型数中各位上为奇数的数依次取出&#xff0c;构成一个新数放在t中。高位仍在高位&#xff0c;低位仍在低位。例如&#xff0c;当s中的数为87653142时&#xff0c;t中的数…

ccs变量观察窗口在哪_CCS3.3查看变量图形

CCS3.3查看变量图形首先声明&#xff0c;觉得ccs3.3中Graph并不是什么量都可以观察的&#xff0c;原因是跟断点有关&#xff0c;反正对于我的仿真器XDS510的是如此。即程序运行到断点处会有延时&#xff0c;对于普通信号可能没什么影响&#xff0c;但对于高频信号来说&#xff…

poj 2777(线段树的节点更新策略)

1 /*2 之前的思想是用回溯的方式进行颜色的更新的&#xff01;如果用回溯的方法的话&#xff0c;就是将每一个节点的颜色都要更新3 通过子节点的颜色情况来判断父节点的颜色情况 &#xff01;这就是TLE的原因&#xff01;4 5 后来想一想没有必要 &#xff01;加入[a, b] 区间有…

c语言计算机编程例题详解,计算机C语言编写程序题及答案解析精选.doc

计算机C语言编写程序题及答案解析精选2011年计算机二级C语言编写程序题及答案解析精选【4.1】已知银行整存整取存款不同期限的月息利率分别为&#xff1a;0.315% 期限一年0.330% 期限二年月息利率 &#xff1d; 0.345% 期限三年0.375% 期限五年0.420% 期限八年要求输入存钱的本…

mfsort shell语法_Shell中字符串排序的几种方法

Shell中字符串排序的几种方法【方法一】按ASCII正向排序备注:1) tr将子字符串中的空白转换为换行符&#xff0c;再用sort排序2) sort无参的话&#xff0c;默认按ASCII正向排序【方法二】按ASCII正向排序备注:1) -r参数: 按ASCII码反向排序2) 在使用sort,uniq等组合命令时候【方…

java中并不是任意多个接口都可以实现多实现

interface A{public abstract void show(); }interface B{public abstract int show(); }public class Test implements A, B{public void show(){System.out.println("A show!");}/*只写 void show&#xff08;&#xff09;出现的问题&#xff1a;Test不是抽象的, 并…

变形监测期末复习_寒假即将来临,中小学期末考试时间是什么时候?

2019年下学期也快结束&#xff0c;各个区的中小学考试时间安排已经公布了。今年&#xff0c;初二将首次进行全市统考&#xff0c;统考的意义重大&#xff0c;希望家长们可以督促孩子们重视起来&#xff0c;考出好成绩!下面&#xff0c;让我们来看一下2019下学期深圳各区中小学期…

c语言2048项目报告,c语言----项目_小游戏2048

2048 小游戏 主要是针对逻辑思维的一个训练.主要学习方面:1.随机数产生的概率.2.行与列在进行移动的时候几种情况.3.messagebox的使用#include #include #include #include using namespace std;int board[4][4] {0}; //二维数组int if_need_rand; //是否生成随机数int if_gam…

java中的显示初始化和特定初始化

public class Test{public static void main(String[] args){Child child new Child();} }class Parent{public Parent(){super();show();//this.show(); 因为是Child类对象调用了super()来构造其父类的部分;所以父类中的this&#xff08;随着其构造方法入栈的&#xff09;是指…

etl工程师 面试题_数据仓库工程师面试题笔试.doc

数据仓库工程师面试题姓名&#xff1a;____张小核______ 开始时间&#xff1a;_____:______ 结束时间&#xff1a;_____:_____数据库使用过哪些数据库&#xff1f;试说出它们的异同。答&#xff1a;使用过SQL SERVER和ORACLE它们的区别是&#xff1a;1.sql server 是中小型企业…

为什叫c语言,为什么c语言叫c语言?

1972年&#xff0c;美国贝尔实验室的 D.M.Ritchie 在B语言的基础上最终设计出了一种新的语言&#xff0c;他取了BCPL的第二个字母作为这种语言的名字&#xff0c;这就是C语言。1973年初&#xff0c;C语言的主体完成。Thompson和Ritchie用它完全重写了UNIX。随着UNIX的发展&…