@@ -52,10 +52,12 @@ public class DisplayActivity extends Activity {
5252 private static final long DEFAULT_REFRESH_MS = 15 * 60 * 1000 ;
5353 private static final String API_DISPLAY_PATH = "/display" ;
5454 private static final String ALARM_REFRESH_ACTION = "com.bpmct.trmnl_nook_simple_touch.ALARM_REFRESH_ACTION" ;
55+ private static final int MAX_WIFI_RECOVERY_ATTEMPTS = 2 ;
5556 /** When true, skip API and show generic on screen (for testing). When false, foreground = API image, screensaver file = generic. */
5657 private static final boolean USE_GENERIC_IMAGE = false ;
5758 /** Delay after showing API image before writing screensaver and going to sleep (show picture, then screensaver, then sleep full interval). */
5859 private static final long SCREENSAVER_DELAY_MS = 2 * 1000 ;
60+ private static final long WIFI_RECOVERY_TOGGLE_DELAY_MS = 2 * 1000 ;
5961 private TextView contentView ;
6062 private TextView logView ;
6163 private ImageView imageView ;
@@ -96,9 +98,11 @@ public class DisplayActivity extends Activity {
9698 /** True while sleepNow() is armed — blocks onResume from re-asserting FLAG_KEEP_SCREEN_ON
9799 * and restoring the 120s screen timeout until the device actually wakes. */
98100 private volatile boolean sleepPending = false ;
101+ private Runnable pendingWifiRecoveryRunnable ;
99102 private Runnable pendingWifiWarmupRunnable ;
100103 private Runnable pendingConnectivityTimeoutRunnable ;
101104 private static final long CONNECTIVITY_MAX_WAIT_MS = 30 * 1000 ;
105+ private volatile int wifiRecoveryAttempts = 0 ;
102106
103107 @ Override
104108 protected void onCreate (Bundle savedInstanceState ) {
@@ -420,6 +424,51 @@ public void run() {
420424 logD ("fetch in " + (WIFI_WARMUP_MS / 1000L ) + "s (wifi warming up)" );
421425 }
422426
427+ private void cancelWifiRecovery () {
428+ if (pendingWifiRecoveryRunnable != null ) {
429+ refreshHandler .removeCallbacks (pendingWifiRecoveryRunnable );
430+ pendingWifiRecoveryRunnable = null ;
431+ }
432+ }
433+
434+ private boolean attemptWifiRecovery (final String reason ) {
435+ final WifiManager wifi = (WifiManager ) getSystemService (Context .WIFI_SERVICE );
436+ if (wifi == null ) {
437+ logW ("wifi recovery unavailable: wifi manager null" );
438+ return false ;
439+ }
440+ if (wifiRecoveryAttempts >= MAX_WIFI_RECOVERY_ATTEMPTS ) {
441+ logW ("wifi recovery exhausted after " + wifiRecoveryAttempts + " attempts" );
442+ return false ;
443+ }
444+ cancelConnectivityWait ();
445+ cancelWifiRecovery ();
446+ wifiRecoveryAttempts ++;
447+ final int attempt = wifiRecoveryAttempts ;
448+ logW ("wifi recovery attempt " + attempt + "/" + MAX_WIFI_RECOVERY_ATTEMPTS + " (" + reason + "), state=" + getWifiStateString ());
449+ try {
450+ wifi .setWifiEnabled (false );
451+ logD ("wifi off for recovery" );
452+ } catch (Throwable t ) {
453+ logW ("wifi off for recovery failed: " + t );
454+ }
455+ pendingWifiRecoveryRunnable = new Runnable () {
456+ @ Override
457+ public void run () {
458+ pendingWifiRecoveryRunnable = null ;
459+ try {
460+ wifi .setWifiEnabled (true );
461+ logD ("wifi on for recovery" );
462+ } catch (Throwable t ) {
463+ logW ("wifi on for recovery failed: " + t );
464+ }
465+ waitForWifiThenFetch ();
466+ }
467+ };
468+ refreshHandler .postDelayed (pendingWifiRecoveryRunnable , WIFI_RECOVERY_TOGGLE_DELAY_MS );
469+ return true ;
470+ }
471+
423472 /** Wait for network to come up, then start fetch. Starts as soon as connectivity appears; max wait CONNECTIVITY_MAX_WAIT_MS. */
424473 private void waitForWifiThenFetch () {
425474 cancelConnectivityWait ();
@@ -463,6 +512,10 @@ public void run() {
463512 logD ("connectivity wait timed out" );
464513 logD ("Ensure you are connected to WiFi. Press the home button and go into settings to configure." );
465514 cancelConnectivityWait ();
515+ if (attemptWifiRecovery ("connectivity timeout" )) {
516+ return ;
517+ }
518+ wifiRecoveryAttempts = 0 ;
466519 if (showErrorInMenu ) {
467520 a .showMenuStatus ("Couldn't connect. Will retry next cycle." , true );
468521 } else {
@@ -803,6 +856,8 @@ private void startFetch() {
803856 if (fetchInProgress ) {
804857 return ;
805858 }
859+ cancelWifiRecovery ();
860+ wifiRecoveryAttempts = 0 ;
806861 fetchInProgress = true ;
807862 fetchStartedFromMenu = menuVisible ;
808863 // Silent background fetch when aggressive sleep is on — no boot status,
0 commit comments