Replace the configurable threshold sliders with two fixed alert levels —
90% and 100% — per metric. Anti-spam now uses hysteresis instead of the
API reset-epoch (which could drift and re-fire): each level fires once
when crossed and re-arms only after usage drops back below it. Alerts are
posted only by the background worker, never the in-app refresh loop, so
you're not pinged while looking at the app. UI drops the sliders for a
one-line description; settings keep just the on/off switch.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the hexagon "C" launcher icon with the tank-crushing-electronics
art. Adaptive icon (anydpi-v26): full art as foreground over teal
#284950 background, so it masks cleanly to any launcher shape; legacy
PNG bitmaps generated for all densities. Refreshes repo-root icon.png.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an in-app 7-day history chart and opt-in usage alerts, the two
features requested from the macOS Claude-Usage-Tracker that map cleanly
to an Android widget app.
History:
- UsageSnapshot model; PreferencesManager records session/weekly
utilization on every refresh (7-day retention, <=600 points, collapses
readings under 2 min apart to avoid worker+manual double-logging).
- HistoryChartView: dependency-free Canvas line chart (session/weekly,
0/50/100% gridlines), breaks the line across >35-min gaps.
- New HISTORY card with chart + legend.
Notifications:
- Notifier posts when session/weekly crosses a user threshold, at most
once per limit window (keyed on reset-epoch, re-arms on rollover).
- USAGE ALERTS card: enable switch + session/weekly sliders (50-100%,
defaults 90/85). POST_NOTIFICATIONS permission + runtime request.
- Wired into the existing 5-min background worker.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Remove the pace marker from the 5-hour (session) bar entirely.
- Weekly bar marker is now a single color (white), no green→purple tiers.
- Marker is a clean rounded tick; removed the white-halo/tier styling.
- Remove the '% over/under pace' text everywhere (widget + app).
- Weekly reset label now shows the weekday ('Resets Friday 3:00 PM'),
never 'tomorrow'.
versionCode 14 / versionName 1.13. Includes rebuilt signed release APK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix v1.11 regression where the pace tag overwrote the reset-time label
(gone entirely on the small widget). The widget reset lines now show the
actual reset time again; pace is conveyed by the bar tick.
Make the pace tick more prominent: wider core + white halo so it stands
out against any fill color.
versionCode 13 / versionName 1.12. Includes rebuilt signed release APK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a pace tick to each usage bar showing where you should be to finish
at 100% by reset, color-coded by projected tier, plus a Claude burst icon
that lights up during Anthropic peak hours (5-11 AM PT, Mon-Fri). Bars now
rendered as bitmaps so the same renderer drives both the widget and the app.
New: PaceCalc, PeakHours, BarRenderer, ic_claude_burst drawable.
versionCode 12 / versionName 1.11. Includes rebuilt signed release APK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make every TextView in both widget layouts fully white (#FFFFFF) with
textStyle=bold — SESSION/WEEKLY labels, session/weekly sub-labels,
status line, and last-updated timestamp.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AndroidManifest: add networkSecurityConfig to explicitly trust only system
CAs, preventing user-installed CA cert MITM attacks on claude.ai sessions
- LoginActivity: set javaScriptCanOpenWindowsAutomatically=false (not needed
for claude.ai login) and databaseEnabled=false (deprecated WebSQL)
- build.gradle.kts: enable buildConfig generation (required for
BuildConfig.DEBUG guards already used in UsageRepository)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- onResume() no longer triggers a refresh every time — only fetches when
data is >5 min stale, so returning to app shows cached data instantly
without a loading spinner
- Fix CancellationException being swallowed by catch(Exception) in
refreshUsage(), which caused updates to run on a destroyed activity
- EncryptedSharedPreferences key invalidation (caused by enabling/changing
biometrics or screen lock) now deletes the stale encrypted file and
recreates it cleanly, rather than silently using empty fallback prefs
- Wrap all securePrefs read/write ops in try-catch so a mid-session
Keystore failure degrades gracefully instead of crashing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two root causes:
- Alarms don't survive reboot — BootReceiver now restarts alarm + triggers
an immediate fetch on BOOT_COMPLETED
- onUpdate() drew from cached prefs but never fetched fresh data — now
triggers an immediate refresh so the widget is live on every launcher redraw
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove KEY_COOKIES_BACKUP plaintext fallback from PreferencesManager
- getCookies() now fails closed (force re-login) if EncryptedSharedPreferences unavailable
- Set android:allowBackup="false" to prevent adb backup extraction of session data
- Add missing gradle-wrapper.jar to repo
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>