From 796b6dffd920ec9228430dcca1a1f4ec855ebfc7 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Sat, 22 Aug 2026 22:35:54 +0000 Subject: Replace background auto-refresh with fetch-on-launch + explicit button Periodic hourly WorkManager fetches and the 5am exact-alarm morning fetch both refreshed without any visible trigger, which surprised the user more than it helped. Refreshing now only ever happens on a fresh app launch (MainActivity.onCreate) or an explicit tap of the new refresh button on the Unread/Older screens' top bar (wired to the fetch-status state that was already being computed there but never rendered). Drops MorningFetchReceiver entirely along with its exact-alarm permission and boot receiver. --- .../java/org/terst/feedreader/ui/MainActivity.kt | 64 ++-------------------- 1 file changed, 4 insertions(+), 60 deletions(-) (limited to 'app/src/main/java/org/terst/feedreader/ui/MainActivity.kt') diff --git a/app/src/main/java/org/terst/feedreader/ui/MainActivity.kt b/app/src/main/java/org/terst/feedreader/ui/MainActivity.kt index 38c04e4..85bc2b3 100644 --- a/app/src/main/java/org/terst/feedreader/ui/MainActivity.kt +++ b/app/src/main/java/org/terst/feedreader/ui/MainActivity.kt @@ -1,12 +1,6 @@ package org.terst.feedreader.ui -import android.app.AlarmManager -import android.content.Intent -import android.net.Uri -import android.os.Build import android.os.Bundle -import android.provider.Settings -import android.util.Log import android.webkit.CookieManager import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -22,13 +16,9 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import org.terst.feedreader.work.FeedFetchWorker -import org.terst.feedreader.work.MorningFetchReceiver import java.net.URLDecoder import java.net.URLEncoder -private const val TAG = "MainActivity" -private const val KEY_REQUESTED_EXACT_ALARM = "requestedExactAlarmPermission" - const val UNREAD_FEED_ID = "__unread__" const val SAVED_FEED_ID = "__saved__" const val OLDER_FEED_ID = "__older__" @@ -42,9 +32,10 @@ fun decodeNavArg(value: String): String = URLDecoder.decode(value, "UTF-8") class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - requestedExactAlarmPermission = savedInstanceState?.getBoolean(KEY_REQUESTED_EXACT_ALARM) ?: false - FeedFetchWorker.schedulePeriodic(applicationContext) - maybeScheduleMorningFetch() + // The only implicit fetch trigger left: a fresh cold launch. No periodic + // WorkManager job and no background alarm any more -- per user request, refreshing + // only ever happens here or from an explicit tap on the refresh button. + FeedFetchWorker.fetchNow(applicationContext) // Explicit, even though it defaults on -- BrowserScreen relies on cookies set // during a site login surviving into the reader's later extraction requests. CookieManager.getInstance().setAcceptCookie(true) @@ -58,53 +49,6 @@ class MainActivity : ComponentActivity() { } } } - - // Re-checked on resume too, not just onCreate -- returning here from the "Alarms & - // reminders" Settings screen (below) is an onResume, not a fresh onCreate, and the - // alarm should get armed the moment permission is actually granted rather than - // needing a full app relaunch. - override fun onResume() { - super.onResume() - maybeScheduleMorningFetch() - } - - // onCreate's own onStart/onResume fires once automatically as part of normal startup, - // right after onCreate -- before the user has done anything -- so without this guard, - // a not-yet-granted permission would launch the Settings screen twice back to back - // (once from onCreate, immediately again from that auto-triggered onResume). Restored - // from savedInstanceState in onCreate (see below), not left as a plain field that - // silently resets to false on every config change -- a rotation while still ungranted - // used to re-trigger the Settings screen every time the device rotated. - private var requestedExactAlarmPermission = false - - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - outState.putBoolean(KEY_REQUESTED_EXACT_ALARM, requestedExactAlarmPermission) - } - - // Runs unconditionally on every onCreate/onResume -- must never let an exception - // escape from here, or a device/OEM quirk around the exact-alarm APIs would crash - // the app on every single launch. A wake-up alarm failing to schedule just isn't - // worth that; worst case it's logged and tries again next launch. - private fun maybeScheduleMorningFetch() { - try { - val alarmManager = getSystemService(AlarmManager::class.java) ?: return - val canScheduleExact = Build.VERSION.SDK_INT < Build.VERSION_CODES.S || alarmManager.canScheduleExactAlarms() - if (canScheduleExact) { - MorningFetchReceiver.scheduleNext(applicationContext) - } else if (!requestedExactAlarmPermission) { - requestedExactAlarmPermission = true - // Android 12+ only: exact alarms require a one-time user grant via Settings, - // there's no in-app permission dialog for this one. Sends the user straight to - // this app's page in the "Alarms & reminders" settings screen. - startActivity( - Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM, Uri.parse("package:$packageName")) - ) - } - } catch (e: Exception) { - Log.e(TAG, "Failed to schedule or request permission for morning fetch", e) - } - } } @Composable -- cgit v1.2.3