首页 > 其他分享 >Android开发 UsageStatsManager应用使用情况管理

Android开发 UsageStatsManager应用使用情况管理

时间:2023-05-23 14:55:44浏览次数:36  
标签:zh 05 23 xx 应用 2023 Android com UsageStatsManager

前言

  UsageStatsManager是用来知晓,设备中应用的使用情况的管理。它能给我们提供应用的进入前台动作与时间戳、进入后台的动作与时间戳、上次的使用时间、使用总时长等等信息。此功能在原生的设置-应用-使用统计中有所展示。

所需权限

<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>

查询当前应用的使用事件

这里使用的是queryEventsForSelf方法,在这个方法返回的数据里包含相同应用每一次进入前后台的时间点。

代码

fun query(context: Context) {
    //查询的开始时间
    val startCalendar = Calendar.getInstance()
    startCalendar.set(Calendar.HOUR_OF_DAY, 0)
    startCalendar.set(Calendar.MINUTE, 0)
    startCalendar.set(Calendar.SECOND, 0)
    //查询的结束时间
    val endCalendar = Calendar.getInstance()
    endCalendar.set(Calendar.HOUR_OF_DAY, 23)
    endCalendar.set(Calendar.MINUTE, 59)
    endCalendar.set(Calendar.SECOND, 59)
    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

    /**
     * 查询当前应用的使用事件
     */
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        val usageEvents = usageStatsManager.queryEventsForSelf(startCalendar.timeInMillis, endCalendar.timeInMillis)
        while (usageEvents.hasNextEvent()) {
            val event = UsageEvents.Event()
            usageEvents.getNextEvent(event)
            when (event.eventType) {
                MOVE_TO_FOREGROUND -> Log.e("zh", "进入前台 ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
                MOVE_TO_BACKGROUND -> Log.e("zh", "退出后台 ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
                else -> Log.e("zh", "其他事件 ${event.eventType} ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
            }
        }
    }
}

结果:

2023-05-23 11:25:37.934 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:24:56
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 11:25:33
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:25:33
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 11:25:34
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:25:34
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 11:25:35
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:25:35
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 11:25:37
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:25:37

查询设备全局应用的使用事件

这里使用的是queryEvents方法

代码

fun query(context: Context) {
    //查询的开始时间
    val startCalendar = Calendar.getInstance()
    startCalendar.set(Calendar.HOUR_OF_DAY, 0)
    startCalendar.set(Calendar.MINUTE, 0)
    startCalendar.set(Calendar.SECOND, 0)
    //查询的结束时间
    val endCalendar = Calendar.getInstance()
    endCalendar.set(Calendar.HOUR_OF_DAY, 23)
    endCalendar.set(Calendar.MINUTE, 59)
    endCalendar.set(Calendar.SECOND, 59)
    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager


    /**
     * 查询设备全局应用的使用事件
     */
    val usageEvents = usageStatsManager.queryEvents(startCalendar.timeInMillis, endCalendar.timeInMillis)
    while (usageEvents.hasNextEvent()) {
        val event = UsageEvents.Event()
        usageEvents.getNextEvent(event)
        when (event.eventType) {
            MOVE_TO_FOREGROUND -> Log.e("zh", "进入前台 ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
            MOVE_TO_BACKGROUND -> Log.e("zh", "退出后台 ${event.packageName} ${simpleDateFormat.format(event.timeStamp)}")
        }
    }
}

结果

2023-05-23 14:09:23.051  6144-6144  zh                      com.xx.dev                         E  进入前台 com.android.launcher3 2023-05-23 14:08:57
2023-05-23 14:09:23.051  6144-6144  zh                      com.xx.dev                         E  退出后台 com.android.launcher3 2023-05-23 14:09:05
2023-05-23 14:09:23.051  6144-6144  zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 14:09:05
2023-05-23 14:09:23.051  6144-6144  zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 14:09:08

查询设备的应用使用统计情况

请注意下面的输入了时间间隔类型UsageStatsManager.INTERVAL_BEST,但是不代表返回的数值就是准确的,比如如果我查询中午12点至下午六点的使用统计,实际上它依然会返回今天应用的全部使用情况

代码

fun query(context: Context) {
    //查询的开始时间
    val startCalendar = Calendar.getInstance()
    startCalendar.set(Calendar.HOUR_OF_DAY, 0)
    startCalendar.set(Calendar.MINUTE, 0)
    startCalendar.set(Calendar.SECOND, 0)
    //查询的结束时间
    val endCalendar = Calendar.getInstance()
    endCalendar.set(Calendar.HOUR_OF_DAY, 23)
    endCalendar.set(Calendar.MINUTE, 59)
    endCalendar.set(Calendar.SECOND, 59)
    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

    /**
     * 查询设备的应用使用统计情况
     */
    val list = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startCalendar.timeInMillis, endCalendar.timeInMillis)
    for (item in list) {
        Log.e("zh", "包名:${item.packageName}")
        Log.e("zh", "开始时间:${simpleDateFormat.format(item.firstTimeStamp)}")
        Log.e("zh", "上次时间戳:${simpleDateFormat.format(item.lastTimeStamp)}")
        Log.e("zh", "最后使用时间:${simpleDateFormat.format(item.lastTimeUsed)}")
        Log.e("zh", "前台总的时间:${item.totalTimeInForeground}")
    }
}

结果

2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  包名:com.android.server.telecom
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  前台总的时间:0
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  包名:android.ext.services
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  前台总的时间:0
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  包名:com.mediatek.capctrl.service
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  前台总的时间:0
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  包名:net.huanci.hsj
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  最后使用时间:2023-05-23 11:10:10
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  前台总的时间:11449
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  包名:com.android.smspush
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  最后使用时间:1970-01-01 08:00:00

查询给定范围内的所有统计数据(使用该范围的最佳间隔)

这里使用的是queryAndAggregateUsageStats方法,这个方法里不需要传入时间间隔参数,并且返回的是map集合。

代码

fun query(context: Context) {
    //查询的开始时间
    val startCalendar = Calendar.getInstance()
    startCalendar.set(Calendar.HOUR_OF_DAY, 0)
    startCalendar.set(Calendar.MINUTE, 0)
    startCalendar.set(Calendar.SECOND, 0)
    //查询的结束时间
    val endCalendar = Calendar.getInstance()
    endCalendar.set(Calendar.HOUR_OF_DAY, 23)
    endCalendar.set(Calendar.MINUTE, 59)
    endCalendar.set(Calendar.SECOND, 59)
    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

    val map = usageStatsManager.queryAndAggregateUsageStats(startCalendar.timeInMillis, System.currentTimeMillis())
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        map.forEach { key, value ->
            Log.e("zh", "包名:${key}")
            Log.e("zh", "开始时间:${simpleDateFormat.format(value.firstTimeStamp)}")
            Log.e("zh", "上次使用时间戳:${simpleDateFormat.format(value.lastTimeStamp)}")
            Log.e("zh", "最后使用时间:${simpleDateFormat.format(value.lastTimeUsed)}")
            Log.e("zh", "前台总的时间:${value.totalTimeInForeground}")
        }
    }
}

结果

2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  包名:net.huanci.hsj
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  开始时间:2023-05-23 09:44:08
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  上次使用时间戳:2023-05-23 14:23:13
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  最后使用时间:2023-05-23 11:10:10
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  前台总的时间:11449
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  包名:com.android.smspush
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  开始时间:2023-05-22 09:38:07
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  上次使用时间戳:2023-05-23 14:23:13
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  最后使用时间:1970-01-01 08:00:23
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  前台总的时间:0
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  包名:com.android.settings
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  开始时间:2023-05-22 09:38:07
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  上次使用时间戳:2023-05-23 09:38:07
2023-05-23 14:38:09.393 11063-11063 zh   com.xx.dev   E  最后使用时间:2023-05-23 09:33:18
2023-05-23 14:38:09.393 11063-11063 zh   com.xx.dev   E  前台总的时间:3328776

时间间隔类型

在上面的方法中,有要求输入查询时间的间隔类型,下面一共提供了4种间隔类型。

/**
 * 跨越一天的间隔类型。参见{@link queryUsageStats(int, long, long)}。
 */
public static final int INTERVAL_DAILY = 0;

/**
 * 跨越一周的间隔类型。参见{@link queryUsageStats(int, long, long)}。
 */
public static final int INTERVAL_WEEKLY = 1;

/**
 * 跨越一个月的间隔类型。参见{@link queryUsageStats(int, long, long)}。
 */
public static final int INTERVAL_MONTHLY = 2;

/**
 * 跨越一年的间隔类型。参见{@link queryUsageStats(int, long, long)}。
 */
public static final int INTERVAL_YEARLY = 3;

/**
 * 一种间隔类型,它将使用给定时间范围的最佳拟合间隔。参见{@link queryUsageStats(int, long, long)}。
 */
public static final int INTERVAL_BEST = 4;

查询当前应用是否活跃

代码

@RequiresApi(Build.VERSION_CODES.M)
fun isAppInactive(context: Context, packageName:String):Boolean {
    val usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
    return usageStatsManager.isAppInactive(packageName)
}

其他api

queryConfigurations(int intervalType, long beginTime, long endTime) 获取指定时间区间内硬件配置信息统计数据。

end

标签:zh,05,23,xx,应用,2023,Android,com,UsageStatsManager
From: https://www.cnblogs.com/guanxinjing/p/17425191.html

相关文章

  • Lazada详情接口的应用
    Lazada是东南亚电商领域的一家知名企业,Lazada商品详情接口是Lazada提供的一种获取Lazada平台商品详细信息的接口。本文将介绍Lazada商品详情接口的使用方法和相关注意事项。第一步:申请访问Lazada商品详情接口在使用Lazada商品详情接口之前,需要先向Lazada申请访问该接口的权......
  • 启发式算法在三维装箱问题上的应用
    启发式算法的出现时间比较难以确定,因为很多算法的提出都是在不同的领域和不同的时间段内,而且随着时间的推移,这些算法也在不断地完善和发展。以下是一些比较有代表性的启发式算法及其出现时间:1953年,模拟退火算法(SimulatedAnnealing,SA)模拟退火算法是一种基于固体物理学中固体退火......
  • Android平台GB28181设备接入模块如何实现实时视频和本地录像双码流编码
    ​技术背景我们在做Android平台GB28181设备接入模块的时候,遇到这样的场景,比如执法记录仪或智慧工地等场景下,由于GB28181设备接入模块,注册到国标平台后,平时只是心跳保持,或还有实时位置订阅,查看视频的时候,是按需看,而且有时候,网络环境并不是太好,所以,催生了这样一个诉求:部分开发者希......
  • 关于AI与api-Java接口的区别应用点
    AI和API是目前互联网技术中的两个趋势,它们在许多领域都发挥了重要作用。在技术的领域中,AI代表的是人工智能,而API代表的是应用程序接口。在本文中,将讨论AI和API的详细分析。AI是人工智能的简称,是指通过计算机技术模拟人类智能的一种技术体系。AI可以学习数据并自我改进,以达到更好的......
  • 修改Android 触摸提示音及音量大小
    一、修改代码提高系统的音量。代码路径:base/services/core/java/com/android/server/audio/AudioService.javaprivatestaticint[]MAX_STREAM_VOLUME=newint[]{5,//STREAM_VOICE_CALL7,//STREAM_SYSTEM7,//STREAM_RING15......
  • 无线振弦传感采集仪在工程监测中的应用解决方案
    无线振弦传感采集仪在工程监测中的应用解决方案 无线振弦传感采集仪是一种高性能的工程监测设备,具有多种优点,如无线传输、高精度、高灵敏度和高可靠性等。在工程监测领域,无线振弦传感采集仪被广泛应用于桥梁、隧道、建筑物等结构物的动态监测、损伤诊断、安全评估和监测预警等......
  • ADG级联备库环境PSU应用验证
    上篇文章源端为备库的场景下Duplicate失败问题我只在中间备库环境应用了PSU,解决了级联备库从中间备库duplicate数据库的问题:细心的朋友已经发现,因为是备库环境,并没有做数据库执行相关脚本部分,所以如果去DB查询补丁应用信息是没有的:SQL>r1*select*fromdba_registry_......
  • 盘点界面控件DevExpress WinForms的几大应用程序主题
    DevExpressWinForm控件包含了50+个自定义皮肤,其中涵盖了MicrosoftOffice和Windows11启发式的应用程序主题。PS:DevExpressWinForm拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForm能完美构建流畅、美观且易于使用的应用程序,无论是Of......
  • 浅析视频技术与AI智能识别技术在智慧矿山场景中的应用
    一、背景分析 能源与矿业是我国国民经济的重要物质生产部门和支柱产业之一,同时也是一个安全事故多发的高危行业,施工阶段的现场管理对工程成本、进度、质量及安全等至关重要。国家矿山安监局陆续发布(矿安〔2022)128号)文、(矿安综〔2023〕5号)文推动矿山重大灾害风险防控,山西、......
  • LLM 应用于编程辅助调研
    目录前言一、能做什么二、局限性三、效果展示四、业界应用五、多产品对比Copilot六、总结1.多产品成熟度2.编程辅助3.业务场景前言AI辅助编程出现之前需要简单重复技艺的修炼,也就是拔刀速度影响了发挥,今后拔刀速度可以忽略了。往后的开发可以思考道为主,反正简单重复技艺的部分......