// ===== Same fix at Kotlin-source level (if you build from the source) ===== // --- new file: widget/IconAlarm.kt --- package com.luachitim.widget import android.app.AlarmManager import android.app.PendingIntent import android.content.Context import android.content.Intent import android.util.Log import com.luachitim.util.DayClock import com.luachitim.util.storedInIsrael object IconAlarm { @Volatile @JvmField var visible = false private fun pending(ctx: Context) = PendingIntent.getBroadcast( ctx, 7005, Intent(ctx, MidnightIconReceiver::class.java).setAction("com.luachitim.action.ICON_TICK"), PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) /** One-shot alarm for the next day change (midnight or tzeit, by the setting). */ fun schedule(ctx: Context) = runCatching { val am = ctx.getSystemService(AlarmManager::class.java) ?: return@runCatching if (!isDynamicIconEnabled()) { am.cancel(pending(ctx)); return@runCatching } val delay = DayClock.millisToNextChange(storedInIsrael(), capMs = 86_400_000L) am.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delay + 3_000, pending(ctx)) }.onFailure { Log.w("LuachItim", "icon alarm schedule failed", it) } } // --- MidnightIconReceiver.onReceive: accept any action, don't swap icon while app is on screen --- override fun onReceive(context: Context, intent: Intent) { runCatching { initAndroidPlatform(context) if (!IconAlarm.visible) applyDynamicIconForToday(context) // schedules next alarm else IconAlarm.schedule(context) // MainActivity.onStop will swap LuachPageWidgetProvider.requestUpdate(context) LuachDateWidgetProvider.requestUpdate(context) LuachWidgetProvider.requestUpdate(context) } } // --- DynamicAppIcon.kt --- // applyDynamicIconForToday(): right after `if (!isDynamicIconEnabled()) return` add: // IconAlarm.schedule(context) // revertToDefaultIcon(): at the end add: // IconAlarm.schedule(context) // cancels, since the feature is now off // --- LuachApplication.onCreate: DON'T swap the icon here (that's the launch "crash") --- // initAndroidPlatform(this) // IconAlarm.schedule(this) // instead of applyDynamicIconForToday(this) // --- MainActivity --- override fun onStart() { super.onStart(); /*...*/ IconAlarm.visible = true } override fun onStop() { /*...*/ super.onStop() IconAlarm.visible = false if (!isChangingConfigurations) runCatching { applyDynamicIconForToday(this) } } // --- AndroidManifest.xml --- // // and in MidnightIconReceiver's intent-filter add: // //