Used Claude to make a screen time app that let's me exclude certain apps A developer used Anthropic's Claude to build TrueScreenTime, a minimal Android app that reconstructs accurate foreground time from UsageEvents and lets users include or exclude specific apps from a custom screen time total. The app, written in Kotlin with XML layouts, features wellbeing-style charts, persistent filters, and a usage access flow, with unit tests running on the JVM via GitHub Actions. A minimal Android app Kotlin + XML layouts, no Compose that reads device usage statistics and lets you build a custom screen time total by including/excluding individual apps. Accurate foreground time — reconstructed from UsageEvents MOVE TO FOREGROUND / MOVE TO BACKGROUND / ACTIVITY STOPPED rather than the pre-bucketed queryUsageStats totals. Wellbeing-style charts — a donut chart of your included apps with the filtered total in the center Today/Custom , and a weekly bar chart with hour gridlines and a tappable day selector This Week . Both are small custom View s — no chart library. Date ranges — Today, This Week Monday-based , or a custom start/end date picked from calendar dialogs. Filterable app list — every app with usage in the range is listed with its icon, name, and time, sorted descending. A checkbox on each row includes/excludes it from the big total, which updates live. Exclusion list — unchecking an app hides it from the list and leaves it out of the total. A dedicated Excluded screen lists everything you have excluded so you can restore apps individually or all at once, and a "Show excluded apps" toggle brings them back inline. Persistent filters — inclusion choices and the "show system apps" / "show excluded apps" toggles are stored in SharedPreferences . System app toggle — system apps and the launcher are hidden by default to reduce clutter. Usage access flow — if PACKAGE USAGE STATS isn't granted, the app shows an explanation and a Grant Access button that deep-links to Settings.ACTION USAGE ACCESS SETTINGS . ./gradlew testDebugUnitTest — everything runs on the JVM in about a minute; no device or emulator involved. GitHub Actions runs this job on every push, and the APK is only built if it passes. | Layer | What it covers | |---|---| | Pure logic | ForegroundSessionReplay session reconstruction from usage events , WeekNavigator day/week stepping , AppListFilter system/excluded filtering and totals , DateRange midnight and week boundaries | | Robolectric | FilterStore against real SharedPreferences , and a smoke test that launches every activity to catch inflation or view-binding failures the compiler cannot see | The pattern is deliberate: logic that used to live inside the activities is extracted into plain Kotlin objects, so the interesting behaviour is testable without an emulator and the activities stay thin. Requirements: JDK 17+ and an Android SDK compileSdk 35 . Setting up from scratch on WSL2? See BUILDING.md /DaanyaalSobani/truescreentime/blob/claude/android-screentime-tracker-x58u19/BUILDING.md for the exact commands. ./gradlew assembleDebug output: app/build/outputs/apk/debug/app-debug.apk Or grab the debug APK from the Releases /DaanyaalSobani/truescreentime/blob/releases page — it is built by the GitHub Actions workflow in .github/workflows/build.yml . adb install app/build/outputs/apk/debug/app-debug.apk Then open the app and tap Grant Access to enable Usage Access. Because the app is sideloaded, Android gates Usage Access behind "restricted settings" and the first attempt is denied. The full flow: | 1. Tap Grant Access | 2. First attempt is denied | 3. Allow restricted settings | 4. Turn the toggle on | |---|---|---|---| Step by step: - Open TrueScreenTime and tap Grant Access — it deep-links to the Usage Access settings, but the toggle is blocked at first "App was denied access" . - Go to Settings → Apps → TrueScreenTime , open the ⋮ overflow menu in the top-right, and tap Allow restricted settings you may be asked to authenticate . - Return to the app, tap Grant Access again, and enable Permit access to app usage data . The grant is remembered until the app is uninstalled. The app never leaves the device with this data — everything stays local. - minSdk 24 Android 7.0 , targetSdk/compileSdk 35 Android 15 - Dependencies: AndroidX core/appcompat/recyclerview/lifecycle, Material Components, Kotlin coroutines — nothing else.