Android 应用使用数据统计服务——UsageStatsManager
2024-01-03 10:57:01
Android 应用使用数据统计服务——UsageStatsManager
先了解下相关知识
UsageStats
UsageStats是在指定时间区间内某个应用使用统计数据的封装类。包含的公开方法及对应的作用如下:
方法 | 用途 |
---|---|
getFirstTimeStamp() | 获取指定时间区间内应用第一次使用时间戳 |
getLastTimeStamp() | 获取指定时间区间内应用最后一次使用时间戳 |
getLastTimeUsed() | 获取应用最后一次使用时间戳 |
getPackageName() | 获取应用包名 |
getTotalTimeInForeground() | 获取应用在前台的时间 |
EventStats
EventStats是在指定时间区间内某个类型事件统计数据的封装类。包含的公开方法及对应的作用如下:
方法 | 用途 |
---|---|
getCount() | 获取在指定时间区间内事件发生的次数 |
getEventType() | 获取事件类型 |
getFirstTimeStamp() | 获取指定时间区间内这个事件第一次发生的时间戳 |
getLastEventTime() | 获取这个事件最后一次发生的时间戳 |
getLastTimeStamp() | 获取指定时间区间内这个事件最后一次发生的时间戳 |
getTotalTime | 获取这个事件总共发生的次数 |
UsageEvents
UsageEvents是用来返回指定时间区间内组件状态变化事件数据的封装类,其返回的组件状态变化事件类型如下:
UsageEvents.Event:
public static final int NONE = 0;
public static final int MOVE_TO_FOREGROUND = 1;
public static final int MOVE_TO_BACKGROUND = 2;
public static final int END_OF_DAY = 3;
public static final int CONTINUE_PREVIOUS_DAY = 4;
public static final int CONFIGURATION_CHANGE = 5;
public static final int SYSTEM_INTERACTION = 6;
public static final int USER_INTERACTION = 7;
public static final int SHORTCUT_INVOCATION = 8;
public static final int CHOOSER_ACTION = 9;
public static final int NOTIFICATION_SEEN = 10;
public static final int STANDBY_BUCKET_CHANGED = 11;
public static final int NOTIFICATION_INTERRUPTION = 12;
public static final int SLICE_PINNED_PRIV = 13;
public static final int SLICE_PINNED = 14;
public static final int SCREEN_INTERACTIVE = 15;
public static final int SCREEN_NON_INTERACTIVE = 16;
public static final int KEYGUARD_SHOWN = 17;
public static final int KEYGUARD_HIDDEN = 18;
UsageStatsManager
**UsageStatsManager 是Android提供统计应用使用情况的服务。通过这个服务可以获取指定时间区间内应用使用统计数据、组件状态变化事件统计数据以及硬件配置信息统计数据。**提供的主要查询方法如下表:
方法 | 用途 |
---|---|
queryAndAggregateUsageStats(long beginTime, long endTime) | 获取指定时间区间内使用统计数据,以应用包名为键值进行数据合并。 |
queryConfigurations(int intervalType, long beginTime, long endTime) | 获取指定时间区间内硬件配置信息统计数据。 |
queryEventStats(int intervalType, long beginTime, long endTime) | 获取指定时间区间内发生组件状态变化事件统计数据。 |
queryEvents(long beginTime, long endTime) | 获取指定时间区间内组件状态变化事件 |
queryEventsForSelf(long beginTime, long endTime) | 与queryEvents相似,获取指定时间区间内本应用的组件状态变化事件 |
queryUsageStats(int intervalType, long beginTime, long endTime) | 获取指定时间区间内应用使用统计数据。 |
查询时间间隔如下:
public static final int INTERVAL_DAILY = 0;
public static final int INTERVAL_WEEKLY = 1;
public static final int INTERVAL_MONTHLY = 2;
public static final int INTERVAL_YEARLY = 3;
public static final int INTERVAL_BEST = 4;
除了上述查询方法,UsageStatsManager还提供了一些其他的重要方法。
方法 | 用途 |
---|---|
isAppInactive(String packageName) | 判断应用是否处于活跃状态 |
setAppInactive(String packageName, boolean inactive) | 设置应用活跃状态,系统API |
registerAppUsageObserver(int observerId, @NonNull String[] packages, long timeLimit,@NonNull TimeUnit timeUnit, @NonNull PendingIntent callbackIntent) | 注册应用使用观察者,系统API |
unregisterAppUsageObserver(int observerId) | 注销应用使用观察者,系统API |
获取顶部应用示例
使用步骤如下:
1、在AndroidManifest.xml中声明权限。
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
2、启动授权设置界面
public static void checkUsageStateAccessPermission(Context context) {
if(!AppUsageUtil.checkAppUsagePermission(context)) {
AppUsageUtil.requestAppUsagePermission(context);
}
}
public static boolean checkAppUsagePermission(Context context) {
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
if(usageStatsManager == null) {
return false;
}
long currentTime = System.currentTimeMillis();
// try to get app usage state in last 1 min
List<UsageStats> stats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTime - 60 * 1000, currentTime);
if (stats.size() == 0) {
return false;
}
return true;
}
public static void requestAppUsagePermission(Context context) {
Intent intent = new Intent(android.provider.Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.i(TAG,"Start usage access settings activity fail!");
}
}
3、查询10秒钟前应用使用统计数据并根据最后使用时间进行排序,得到的最后使用的应用。
public static String getTopActivityPackageName( Context context) {
final UsageStatsManager usageStatsManager = (UsageStatsManager)context.getSystemService(Context.USAGE_STATS_SERVICE);
if(usageStatsManager == null) {
return PACKAGE_NAME_UNKNOWN;
}
String topActivityPackageName = PACKAGE_NAME_UNKNOWN;
long time = System.currentTimeMillis();
// 查询最后十秒钟使用应用统计数据
List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*10, time);
// 以最后使用时间为标准进行排序
if(usageStatsList != null) {
SortedMap<Long,UsageStats> sortedMap = new TreeMap<Long,UsageStats>();
for (UsageStats usageStats : usageStatsList) {
sortedMap.put(usageStats.getLastTimeUsed(),usageStats);
}
if(sortedMap.size() != 0) {
topActivityPackageName = sortedMap.get(sortedMap.lastKey()).getPackageName();
Log.d(TAG,"Top activity package name = " + topActivityPackageName);
}
}
return topActivityPackageName;
}
dump命令
adb shell dumpsys usagestats
获取最近一段时间打开应用的示例
判断某第三方应用这个时间是否打开
使用UsageStatsManager可以获取应用程序的使用情况,包括应用程序的包名、启动时间、使用时间等。判断第三方应用是否打开,可以通过以下步骤实现:
- 获取UsageStatsManager实例:
UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
- 获取当前时间和一段时间前的时间:
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.DAY_OF_MONTH, -1);
long startTime = calendar.getTimeInMillis();
- 获取应用程序的使用情况列表:
List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime);
- 遍历使用情况列表,判断第三方应用是否打开:
for (UsageStats usageStats : usageStatsList) {
if ((usageStats.getPackageName().equals(packageName)) && (usageStats.getLastTimeUsed() > 0)) {
// 第三方应用已经打开
}
}
其中,packageName为第三方应用的包名。如果该应用的最后使用时间(getLastTimeUsed())大于0,则表示该应用已经打开。
小结
本文基于Android9.0 SDK列举了应用使用数据统计服务UsageStatsManager所能提供的服务,并给出获取顶部应用的代码示例。其他获取前台应用的方法可以参看《4种获取前台应用的方法(肯定有你不知道的)》,里面关于UsageStatsManager使用的相关优化可以学习一下。
参考
文章来源:https://blog.csdn.net/fromVillageCoolBoy/article/details/135355449
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!