Skip to content

Commit e771d92

Browse files
timbortnikclaude
andcommitted
Remove USER_PRESENT handler for consistent widget behavior
USER_PRESENT broadcast only works when the app process is running (runtime registration required since Android 8.0), causing inconsistent behavior depending on whether the app was killed by the OS. Widget updates now rely solely on: - updatePeriodMillis (30 min) for system-triggered updates - WorkManager periodic task for background weather fetches - CONNECTIVITY_CHANGE for faster response when network returns This provides consistent behavior regardless of app state. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 05f8de2 commit e771d92

2 files changed

Lines changed: 10 additions & 29 deletions

File tree

‎android/app/src/main/kotlin/org/bortnik/meteogram/MeteogramApplication.kt‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class MeteogramApplication : Application() {
3636
/**
3737
* Register ContentObserver for immediate Material You color change detection.
3838
* This fires instantly when colors change (while app process is alive).
39-
* WorkManager and USER_PRESENT provide fallback when app is killed.
39+
* WorkManager provides fallback when app is killed.
4040
*/
4141
private fun registerThemeObserver() {
4242
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return
@@ -75,15 +75,15 @@ class MeteogramApplication : Application() {
7575

7676
// LOCALE_CHANGED and TIMEZONE_CHANGED are handled by manifest-declared receiver
7777
// (required because app process is killed on locale change)
78-
// USER_PRESENT and CONNECTIVITY_CHANGE require runtime registration
78+
// CONNECTIVITY_CHANGE requires runtime registration
79+
// Note: USER_PRESENT removed - it only works when app is running, causing inconsistent behavior
7980
val filter = IntentFilter().apply {
80-
addAction(Intent.ACTION_USER_PRESENT)
8181
addAction("android.net.conn.CONNECTIVITY_CHANGE")
8282
}
8383

84-
// Use RECEIVER_EXPORTED to receive system broadcasts (USER_PRESENT, etc.)
84+
// Use RECEIVER_EXPORTED to receive system broadcasts
8585
registerReceiver(widgetEventReceiver, filter, RECEIVER_EXPORTED)
8686
receiverRegistered = true
87-
Log.d(TAG, "Widget event receiver registered (runtime: USER_PRESENT, CONNECTIVITY_CHANGE)")
87+
Log.d(TAG, "Widget event receiver registered (runtime: CONNECTIVITY_CHANGE)")
8888
}
8989
}

‎android/app/src/main/kotlin/org/bortnik/meteogram/WidgetEventReceiver.kt‎

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@ import android.content.Context
55
import android.content.Intent
66
import android.net.ConnectivityManager
77
import android.net.NetworkCapabilities
8-
import android.os.Build
98
import android.util.Log
109

1110
/**
1211
* BroadcastReceiver for system events that trigger widget updates.
1312
*
1413
* Registration:
15-
* - USER_PRESENT, CONNECTIVITY_CHANGE: Runtime (in MeteogramApplication)
14+
* - CONNECTIVITY_CHANGE: Runtime (in MeteogramApplication)
1615
* - LOCALE_CHANGED, TIMEZONE_CHANGED: Manifest (app killed on change)
1716
*
17+
* Note: USER_PRESENT was removed because it only works when app process is running,
18+
* causing inconsistent behavior. Widget updates rely on updatePeriodMillis (30 min)
19+
* and WorkManager for consistent behavior regardless of app state.
20+
*
1821
* Note: CONNECTIVITY_CHANGE is deprecated since Android 7.0 (API 24).
1922
* On newer devices, connectivity changes may be delayed or batched.
20-
* For more reliable network monitoring, consider using:
21-
* - ConnectivityManager.registerNetworkCallback() for API 21+
22-
* - WorkManager with NetworkType.CONNECTED constraint
2323
* Current implementation uses WorkManager periodic task as primary mechanism,
2424
* with CONNECTIVITY_CHANGE as supplementary for faster response on older devices.
2525
*/
@@ -32,15 +32,6 @@ class WidgetEventReceiver : BroadcastReceiver() {
3232
Log.d(TAG, "Received broadcast: ${intent.action}")
3333

3434
when (intent.action) {
35-
Intent.ACTION_USER_PRESENT -> {
36-
// Screen unlocked - re-render only if needed:
37-
// 1. Crossed 30-min boundary (now indicator moved)
38-
// 2. Weather data updated while locked (background fetch)
39-
Log.d(TAG, "User present - checking if re-render needed")
40-
updateMaterialYouColors(context)
41-
WidgetUtils.rerenderAllWidgetsIfNeeded(context)
42-
fetchWeatherIfStale(context)
43-
}
4435
Intent.ACTION_LOCALE_CHANGED -> {
4536
// Locale changed - re-render with new units/format
4637
Log.d(TAG, "Locale changed - triggering re-render")
@@ -61,16 +52,6 @@ class WidgetEventReceiver : BroadcastReceiver() {
6152
}
6253
}
6354

64-
private fun updateMaterialYouColors(context: Context) {
65-
// Update Material You colors if changed (Android 12+)
66-
// Does NOT trigger re-render - caller handles that
67-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
68-
if (MaterialYouColorExtractor.updateColorsIfChanged(context)) {
69-
Log.d(TAG, "Material You colors updated")
70-
}
71-
}
72-
}
73-
7455
private fun fetchWeatherIfStale(context: Context) {
7556
WidgetUtils.fetchWeatherIfStale(context)
7657
}

0 commit comments

Comments
 (0)