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

Demo

获取最近一段时间打开应用的示例

判断某第三方应用这个时间是否打开

使用UsageStatsManager可以获取应用程序的使用情况,包括应用程序的包名、启动时间、使用时间等。判断第三方应用是否打开,可以通过以下步骤实现:

  1. 获取UsageStatsManager实例:
UsageStatsManager usageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
  1. 获取当前时间和一段时间前的时间:
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.DAY_OF_MONTH, -1);
long startTime = calendar.getTimeInMillis();
  1. 获取应用程序的使用情况列表:
List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime);
  1. 遍历使用情况列表,判断第三方应用是否打开:
for (UsageStats usageStats : usageStatsList) {
    if ((usageStats.getPackageName().equals(packageName)) && (usageStats.getLastTimeUsed() > 0)) {
        // 第三方应用已经打开
    }
}

其中,packageName为第三方应用的包名。如果该应用的最后使用时间(getLastTimeUsed())大于0,则表示该应用已经打开。

小结

本文基于Android9.0 SDK列举了应用使用数据统计服务UsageStatsManager所能提供的服务,并给出获取顶部应用的代码示例。其他获取前台应用的方法可以参看《4种获取前台应用的方法(肯定有你不知道的)》,里面关于UsageStatsManager使用的相关优化可以学习一下。

参考

(Android 9.0)应用使用数据统计服务——UsageStatsManager

文章来源:https://blog.csdn.net/fromVillageCoolBoy/article/details/135355449
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。