文档章节

获取App使用记录

小孩er
 小孩er
发布于 2016/07/28 15:35
字数 711
阅读 65
收藏 0
点赞 0
评论 0

使用UsageStatsManager获取app运行记录

UsageStatsManager出现在android 5.0 API21之后,5.0之前是没有这个类的

	// 获取app的UsageStats
	public static List<UsageStats> getUsageStatsList(Context context) {
		UsageStatsManager usm = (UsageStatsManager) context
				.getSystemService("usagestats");
		Calendar calendar = Calendar.getInstance();
		long endTime = calendar.getTimeInMillis();
		calendar.add(Calendar.YEAR, -1);
		long startTime = calendar.getTimeInMillis();
		List<UsageStats> usageStatsList = usm.queryUsageStats(
				UsageStatsManager.INTERVAL_DAILY, startTime, endTime);
		return usageStatsList;
	}

	// 读取UsageStats里数据
	public static void printUsageStats(List<UsageStats> usageStatsList)
			throws IllegalAccessException, IllegalArgumentException,
			NoSuchFieldException {
		for (UsageStats u : usageStatsList) {
			String pkgName = u.getPackageName();// 包名
			Long foregroundtime = u.getTotalTimeInForeground();// 运行时长:
			int launcherCount = u.getClass().getDeclaredField("mLaunchCount")
					.getInt(u);// 运行次数,不能直接访问,反射获取
		}
	}

通常情况下默认是拿不到数据的,需要给予权限,并打开相应开关,部分手机开关页是隐藏的,需要代码跳转。

//需要的权限,再manifest注册后,则可以在“查看使用情况权限”控制页控制本app
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
//跳转的方法
public static void statrtUsageAccessActivity(Context context) {
	Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
	context.startActivity(intent);
}

/data/system/usagestats 

-rw------- system   system      12992 2016-07-23 08:31 usage-20160722
-rw------- system   system       6532 2016-07-24 01:11 usage-20160723
-rw------- system   system        976 2016-07-25 08:18 usage-20160724
-rw------- system   system       9848 2016-07-26 05:25 usage-20160725
-rw------- system   system       7308 2016-07-26 17:57 usage-20160726
-rw------- system   system      50802 2016-07-26 05:25 usage-history.xml

其中usage-history.xml如下

<usage-history>
    <pkg name="com.sogou.activity.src">
        <comp name="com.sogou.weixintopic.read.WeixinHeadlineReadFirstActivity" lrt="1468237211692" />
        <comp name="com.sogou.activity.src.wxapi.WXEntryActivity" lrt="1467711877007" />
        <comp name="com.sogou.activity.src.SplashActivity" lrt="1468501310396" />
        <comp name="com.sogou.search.result.SuggestionActivity" lrt="1468237220015" />
        <comp name="com.sogou.search.result.SogouSearchActivity" lrt="1468405345331" />
        <comp name="com.sogou.activity.src.NewUserAnimGuideActivity" lrt="1467689925626" />
        <comp name="com.sogou.weixintopic.read.PicNewsReadActivity" lrt="1467710313758" />
        <comp name="com.sogou.weixintopic.read.activity.CommentListActivity" lrt="1467710289689" />
        <comp name="com.sogou.search.entry.EntryActivity" lrt="1468501310836" />
    </pkg>
    <pkg name="com.xiaomi.account">
        <comp name="com.xiaomi.account.ui.AuthorizeActivity" lrt="1466477718040" />
        <comp name="com.xiaomi.account.ui.LoginActivity" lrt="1465135903157" />
        <comp name="com.xiaomi.account.ui.AccountSettingsActivity" lrt="1465199758416" />
        <comp name="com.xiaomi.account.ui.WelcomeActivity" lrt="1465135903193" />
        <comp name="com.xiaomi.account.ui.UserDetailInfoActivity" lrt="1465175067590" />
        <comp name="com.xiaomi.account.ui.SnsListActivity" lrt="1465135914454" />
    </pkg>
    <pkg name="com.android.updater">
        <comp name="com.android.updater.MainActivity" lrt="1465955978078" />
    </pkg>
...............
</usage-history>

-----------------------分割线---------------------------------

4.4.4之前 

 com.android.internal.app.IUsageStats

 android 4.4.4_r1 4.4.3_r1 4.4.2_r1 4.4.1_r1 4.4_r1 4.3.1_r1 4.3_r2.1 4.3_r1 

4.2.2_r14.2.1_r1.2 4.2_r1 4.1.2_r1 4.1.1_r1 、4.0.4_r2.1 4.0.4_r1.2 2.0_r1 ...

应该是可以通过这个类获取相关信息

需要系统级app才可以

参考链接:blog.csdn.net/tanwei4199/article/details/17527145

// use reflect
	// have to root and push into system/app
	private void getPkgUsageStats()
    {
		try {
			Class<?> cServiceManager = Class
					.forName("android.os.ServiceManager");
			Method mGetService = cServiceManager.getMethod("getService",
					java.lang.String.class);
			Object oRemoteService = mGetService.invoke(null, "usagestats");

			// IUsageStats oIUsageStats =
			// IUsageStats.Stub.asInterface(oRemoteService)
			Class<?> cStub = Class
					.forName("com.android.internal.app.IUsageStats$Stub");
			Method mUsageStatsService = cStub.getMethod("asInterface",
					android.os.IBinder.class);
			Object oIUsageStats = mUsageStatsService.invoke(null,
					oRemoteService);

			// PkgUsageStats[] oPkgUsageStatsArray =
			// mUsageStatsService.getAllPkgUsageStats();
			Class<?> cIUsageStatus = Class
					.forName("com.android.internal.app.IUsageStats");
			Method mGetAllPkgUsageStats = cIUsageStatus.getMethod(
					"getAllPkgUsageStats", (Class[]) null);
			Object[] oPkgUsageStatsArray = (Object[]) mGetAllPkgUsageStats
					.invoke(oIUsageStats, (Object[]) null);
			System.out.println(oPkgUsageStatsArray);

			Class<?> cPkgUsageStats = Class
					.forName("com.android.internal.os.PkgUsageStats");

			StringBuffer sb = new StringBuffer();
			sb.append("nerver used : ");
			for (Object pkgUsageStats : oPkgUsageStatsArray) {
				// get pkgUsageStats.packageName, pkgUsageStats.launchCount,
				// pkgUsageStats.usageTime
				String packageName = (String) cPkgUsageStats.getDeclaredField(
						"packageName").get(pkgUsageStats);
				int launchCount = cPkgUsageStats
						.getDeclaredField("launchCount").getInt(pkgUsageStats);
				long usageTime = cPkgUsageStats.getDeclaredField("usageTime")
						.getLong(pkgUsageStats);
				if(launchCount > 0)
					Log.v("getPkgUsageStats",packageName + "  count: " + launchCount + "  time:  "
						+ usageTime);
				else{
					sb.append(packageName+" ");
				}
			}
			Log.v("getPkgUsageStats",sb.toString());
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 

--------------------------------------------------------------

获取权限除了跳转到页面,手动给予之外 还可以利用下面的方式进行代码操作。

android权限管理--AppOpsManager

    android自带的 ,4.3出现4.4

AppOpsManagerCompat

    v4包下类 用来适配低版本android环境

7.0之后推荐使用 RuntimePermission

© 著作权归作者所有

共有 人打赏支持
小孩er

小孩er

粉丝 0
博文 10
码字总数 3722
作品 0
朝阳
程序员
laravel源码阅读(绑定与解析服务)

1. 环境配置 laravel5.1.46的源码 PHPstorm开发工具 服务器集成环境(mamp、wamp)安装xdebug扩展 2. 关键点 使用PHPstorm+xdebug进行源码阅读时需点击(F7按钮)进入到下一个执行代码的方法...

彩虹的夜晚
05/30
0
0
用Android自带统计服务AppUasge一招制敌

Tamic/文 Google从 API 21 新增了接口 android.app.usage , 通过这个api我们可以统计到每个app的使用情况,启动次数,启动时间等,也可以判断是否前后台,比较方便,今天就来深入的学习一下 ...

Tamic
2017/10/12
0
0
较好用户体验获取 App 使用权限

较好用户体验获取 App 使用权限 目前市面上大多数的 App 获取权限都是在用户在使用该功能的时候弹出获取权限的请求,这样子用户在用的时候弹出来要么给予权限,要么关闭权限这种方式显得用户...

杭城小刘
01/18
0
0
laravel中的错误与日志

日志 laravel中的日志是基于monolog而封装的。laravel在它上面做了几个事情: 把monolog中的addInfo等函数简化成为了info这样的函数 增加了useFiles和useDailyFiles两个参数,使得做日志管理...

王二狗子11
01/07
0
0
ThinkPHP2.2框架执行流程图,ThinkPHP控制器的执行流程

ThinkPHP2.2框架执行原理、流程图在线手册 ThinkPHP控制器的执行流程 对用户的第一次URL访问 http://<serverIp>/My/index.php/Index/show/ 所执行的流程进行详细的分析,用户的URL访问首先是...

leycau
2015/07/27
0
0
ThinkPHP控制器的执行流程

ThinkPHP控制器的执行流程 对用户的第一次URL访问 http://<serverIp>/My/index.php/Index/show/ 所执行的流程进行详细的分析,用户的URL访问首先是定位到了My项目的index.php 入口文件(注意...

雍雍_yoyo
2014/12/10
0
0
自定义统计SDK--TcStatInterface

TcStatInterface是自定义统计SDK,完全放弃第三方平台,让app拥有自主的数据统计功能,支持页面统计自定义事件统计APP启动退出统计,不同渠道统计。 客户端SDK功能概述 在使用统计服务前,开...

匿名
2016/07/05
303
0
59. (android开发)SQLite数据库操作

SQLite数据库是一款轻型的数据库,在很多嵌入式产品中使用。它占用的资源非常低,只需要几百K内存就足够了。 对windows/linux/unix等多种操作系统提供支持。目前SQLite3是最新的版本。 andr...

厚土火焰山
01/06
0
0
xmpp for ios

基于xmpp的即时通讯(需要配置openfire)。包括注册新用户,连接,获取朋友列表,文字通讯和语音通讯。其中保存朋友列表和聊天记录使用的是xmpp框架本身的coredata,没有使用任何其他的自定义的...

红薯
2013/08/26
4.9K
0
Android App内截屏监控及涂鸦功能实现

Android截屏功能是一个常用的功能,可以方便的用来分享或者发送给好友,本文介绍了如何实现app内截屏监控功能,当发现用户在我们的app内进行了截屏操作时,将自动展示该截屏,并提供用户随意...

JackMeGo
2017/04/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Dubbo 源码解读 —— 可支持序列化及自定义扩展

一、概述 从源码中,我们可以看出来。目前,Dubbo 内部提供了 5 种序列化的方式,分别为 fastjson、Hessian2、Kryo、fst 及 Java原生支持的方式 。 针对不同的序列化方式,对比内容如下: 名...

Ryan-瑞恩
10分钟前
0
0
MySQL内存设置—— MySQL server has gone away

set global max_allowed_packet=268435456

一梦心草
19分钟前
0
0
推导式

列表、集合和字典推导式 列表推导式是Python最受喜爱的特性之一。它允许用户方便的从一个集合过滤元素,形成列表,在传递参数的过程中还可以修改元素。形式如下: [expr for val in collect...

火力全開
24分钟前
0
0
maven配置文件settings.xml详解

settings.xml有什么用? 如果在Eclipse中使用过Maven插件,想必会有这个经验:配置settings.xml文件的路径。 settings.xml文件是干什么的,为什么要配置它呢? 从settings.xml的文件名就可以...

浮躁的码农
29分钟前
0
0
MakeCode图形化编程语言学习笔记:micro:bit编程练习题[图]

MakeCode图形化编程语言学习笔记:micro:bit编程练习题[图]: 基础训练题: Q1:摇晃micro:bit编程板,随机出现7个小动物图标中的一个,并且前后相邻两次出现的小动物不重复。 注:七个小动物...

原创小博客
29分钟前
0
0
Redis 压力测试说明

Redis 压力测试说明 redis压力测试 2014-03-24 21:41:07| 分类: 默认分类 | 标签:redis |举报|字号 订阅 这几天对比测试mongodb、redis、pg的性能,主要是在消息队列、消息处理、用户经纬度...

舒文joven
30分钟前
0
0
拉姆达表达式 追加 条件判断 Expression>

public static class PredicateBuilder {   /// <summary>   /// 机关函数应用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混应时写在AND后的OR有效   /// </summary...

Lytf
42分钟前
0
0
【HAVENT原创】Spring Boot + Kafka 消息日志开发

最近因为部门需要将服务程序的各种日志发送给 Kafka 进行分析,所以写一个 Kafka 消息日志操作类,主要用来保存日志到 Kafka 以便查询。 一、pom.xml 增加配置 <!-- HH: 引入 kafka 模块 ...

HAVENT
43分钟前
0
0
7、Git命令解析

1、创建版本库 cd E:mkdir myRepositorypwdls -ah======git init 2、添加文件到仓库 添加git add readme.txt提交git commit -m "i wrote a readme file"【为什么Git添加...

丑陋的皮囊
43分钟前
0
0
ImageMagick批量压缩图片

#!/bin/shfor img in `find ./image -name "*.jpg"`; donewimg=`basename $img` convert -quality 75% $img ./ok/$newimg echo ./ok/$newimgdone...

dworry
43分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部