You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Studio中获取设备屏幕唤醒时长及分周期总使用时长?

Hey there! Let's break down how to get screen wake duration and aggregated device usage stats by day/week/month/year in Android Studio, since UsageStats only gives app-specific data.

1. First Things First: Required Permissions

Before diving into code, you need to handle the special permission for usage stats:

  • Add this to your AndroidManifest.xml:
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
        tools:ignore="ProtectedPermissions" />
    
  • This permission can't be granted via regular runtime requests. You'll need to guide users to enable it manually in Settings:
    fun checkUsageStatsPermission(context: Context): Boolean {
        val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
        val mode = appOps.checkOpNoThrow(
            AppOpsManager.OPSTR_GET_USAGE_STATS,
            android.os.Process.myUid(),
            context.packageName
        )
        return mode == AppOpsManager.MODE_ALLOWED
    }
    
    fun openUsageStatsSettings(context: Context) {
        val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
        context.startActivity(intent)
    }
    
2. Get Total Screen Wake Duration

To calculate how long the screen has been awake, we'll use UsageStatsManager to track EVENT_SCREEN_ON and EVENT_SCREEN_OFF events, then sum the time differences between each pair:

fun calculateTotalScreenWakeTime(context: Context): Long {
    val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
    val startTime = 0L // Start from device boot time, or set a custom start timestamp
    val endTime = System.currentTimeMillis()

    val events = usageStatsManager.queryEvents(startTime, endTime)
    var totalWakeTime = 0L
    var lastScreenOnTime = 0L

    while (events.hasNextEvent()) {
        val event = UsageEvents.Event()
        events.getNextEvent(event)
        when (event.eventType) {
            UsageEvents.Event.EVENT_SCREEN_ON -> {
                lastScreenOnTime = event.timeStamp
            }
            UsageEvents.Event.EVENT_SCREEN_OFF -> {
                if (lastScreenOnTime != 0L) {
                    totalWakeTime += event.timeStamp - lastScreenOnTime
                    lastScreenOnTime = 0L
                }
            }
        }
    }

    // Add time if screen is currently awake
    val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
    if (powerManager.isInteractive && lastScreenOnTime != 0L) {
        totalWakeTime += System.currentTimeMillis() - lastScreenOnTime
    }

    return totalWakeTime // Returns duration in milliseconds
}
3. Aggregate Usage Stats by Day/Week/Month/Year

To get stats for specific time intervals, we'll split the overall time range into chunks (days, weeks, etc.) and calculate wake time for each chunk:

Example: Daily Wake Stats

fun getDailyWakeStats(context: Context, startDate: Long, endDate: Long): Map<String, Long> {
    val dailyStats = mutableMapOf<String, Long>()
    val calendar = Calendar.getInstance().apply {
        timeInMillis = startDate
        set(Calendar.HOUR_OF_DAY, 0)
        set(Calendar.MINUTE, 0)
        set(Calendar.SECOND, 0)
        set(Calendar.MILLISECOND, 0)
    }

    var currentDayStart = calendar.timeInMillis
    val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())

    while (currentDayStart <= endDate) {
        val currentDayEnd = currentDayStart + 24 * 60 * 60 * 1000 - 1 // End of the day
        val dayKey = dateFormat.format(Date(currentDayStart))
        val dayWakeTime = calculateWakeTimeForPeriod(context, currentDayStart, currentDayEnd)
        dailyStats[dayKey] = dayWakeTime

        // Move to next day
        calendar.add(Calendar.DAY_OF_MONTH, 1)
        currentDayStart = calendar.timeInMillis
    }

    return dailyStats
}

// Reusable function to calculate wake time for a specific time period
private fun calculateWakeTimeForPeriod(context: Context, startTime: Long, endTime: Long): Long {
    val usageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
    val events = usageStatsManager.queryEvents(startTime, endTime)
    var totalWakeTime = 0L
    var lastScreenOnTime = 0L

    while (events.hasNextEvent()) {
        val event = UsageEvents.Event()
        events.getNextEvent(event)
        when (event.eventType) {
            UsageEvents.Event.EVENT_SCREEN_ON -> lastScreenOnTime = event.timeStamp
            UsageEvents.Event.EVENT_SCREEN_OFF -> {
                if (lastScreenOnTime != 0L) {
                    totalWakeTime += event.timeStamp - lastScreenOnTime
                    lastScreenOnTime = 0L
                }
            }
        }
    }

    // Handle case where screen is still awake at end of period
    if (endTime >= System.currentTimeMillis()) {
        val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
        if (powerManager.isInteractive && lastScreenOnTime != 0L) {
            totalWakeTime += System.currentTimeMillis() - lastScreenOnTime
        }
    }

    return totalWakeTime
}

Extending to Week/Month/Year

For weekly stats, adjust the calendar logic to increment Calendar.WEEK_OF_YEAR instead of DAY_OF_MONTH. Similarly, use Calendar.MONTH for monthly stats and Calendar.YEAR for yearly stats. Just make sure to set the start of each interval correctly (e.g., start of the week, start of the month).

Key Notes
  • Compatibility: UsageStatsManager is available from API 21 (Android 5.0). For older devices, you'll need alternative methods (like reading system logs, which is less reliable and requires more permissions).
  • Data Retention: System usage events aren't stored indefinitely. Older data (e.g., months back) might not be available depending on device settings.
  • Definition of "Usage": This solution tracks screen wake time. If you need to measure overall device activity (even with screen off), you'd need to combine this with other metrics like CPU usage or idle state checks via PowerManager.

内容的提问来源于stack exchange,提问作者Sai Shiva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:53:41