You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HMG_QLine/QUICK_SUMMARY.md

6.5 KiB

dt# Quick Summary - Changes Made (March 1, 2026)

Device Context

Important: These are AC-powered Android LED kiosk displays, not battery-powered tablets. The issue is not battery drain, but Android OS killing "idle" apps even on plugged-in devices.

Problem Identified from Logs

  • App started ~midnight Feb 26
  • Ran successfully with health checks until 8:36 AM Feb 27 (~14 hours)
  • Completely stopped logging after 8:36 AM
  • No crash logs, no lifecycle events
  • User manually restarted March 1 at 10:54 AM

Root Cause

Android OS killed the app after ~14 hours because:

  1. Android treats long-running apps as "idle" even on AC power
  2. No user interaction for extended periods
  3. Android's background task restrictions kicked in
  4. App wasn't in proper kiosk/foreground mode

Critical Changes Made

1. Fixed Uptime Tracking Bug ⚠️ CRITICAL

File: lib/view_models/screen_config_view_model.dart

Problem:

// WRONG - calculated time since last MIDNIGHT, not app start
DateTime.now().difference(lastChecked).inHours

Solution:

DateTime appStartTime = DateTime.now(); // Track actual start time
final uptimeHours = DateTime.now().difference(appStartTime).inHours;

Impact: Now you'll see accurate uptime like:

Health check performed - App uptime: 14h 23m (started: 2026-02-26 20:00:00)

2. Android Kiosk Display Mode ⚠️ CRITICAL

Files:

  • android/app/src/main/AndroidManifest.xml
  • android/app/src/main/kotlin/.../MainActivity.kt

Changes:

  1. Added window flags to prevent sleep/idle:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)
    window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
    window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD)
    window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
}
  1. Added activity flags in manifest:
android:keepScreenOn="true"
android:screenOrientation="portrait"

Impact: Prevents Android from treating app as "idle" and killing it. No user dialogs needed - works automatically.


3. Failure Detection & Auto-Recovery

File: lib/view_models/screen_config_view_model.dart

Added:

  • Track consecutive health check failures
  • After 3 failures, automatically restart SignalR connection
  • Log critical warnings
int healthCheckFailures = 0;

try {
    syncHubConnectionState();
    healthCheckFailures = 0; // Reset on success
} catch (e) {
    healthCheckFailures++;
    if (healthCheckFailures >= 3) {
        // Restart connection
        await queuingViewModel.stopHubConnection();
        await Future.delayed(const Duration(seconds: 2));
        await queuingViewModel.startHubConnection();
    }
}

4. Enhanced Lifecycle Tracking

File: lib/view_models/screen_config_view_model.dart

Changes:

  • Log actual uptime in lifecycle events
  • Track when app goes to background
  • Track when app is killed

New Logs:

[onAppPaused] - App uptime: 14h - WARNING: App going to background!
[onAppDetached] - App uptime: 14h - CRITICAL: App being killed!

Impact: You'll now see EXACTLY when and why the app dies


5. Clinic Prefix Feature

File: lib/models/global_config_model.dart

Added:

bool globalClinicPrefixReq = false;
bool clinicPrefixReq = true;

bool isClinicPrefixAdded(String ticketNo) {
  final hasClinicPrefix = RegExp(r'^[A-Za-z]{3} W-').hasMatch(ticketNo);
  return hasClinicPrefix;
}

Returns true for: "XXX W-78" (3 letters + space + W-) Returns false for: "W-A-12", "XX-12", "X-7", etc.


Files Modified

  1. lib/view_models/screen_config_view_model.dart
  2. lib/models/global_config_model.dart
  3. lib/repositories/signalR_repo.dart
  4. android/app/src/main/AndroidManifest.xml
  5. android/app/src/main/kotlin/.../MainActivity.kt
  6. CHANGES_EXPLANATION.md (full documentation)

Next Steps - Deploy & Test

1. Build APK

cd /Volumes/Data/Projects/Flutter/HMG_QLine
flutter clean
flutter build apk --release

2. Deploy to Test Device

adb install -r build/app/outputs/flutter-apk/app-release.apk

3. First Launch Actions

  • No user action required!
  • App automatically configures kiosk display mode
  • Check logs to verify health checks are running

4. Monitor Logs

Look for these every 5 minutes:

[2026-03-01 11:00:00 AM] Health check performed - App uptime: 0h 5m (started: 2026-03-01 10:54:37)
[2026-03-01 11:00:01 AM] Health check - Hub connected: true, Internet: true

Uptime should increment correctly: 0h 5m → 0h 10m → 0h 15m → ... → 14h 0m → 14h 5m

5. What You Should NOT See

If app stays alive, you should NOT see:

  • [onAppPaused] - means app going to background
  • [onAppDetached] - means app being killed

Expected Timeline

Time Expected Behavior
First 5 min Health check logs start appearing
After 1 hour Uptime shows ~1h 0m
After 14 hours ⚠️ CRITICAL CHECKPOINT - App should still be running (previously died here)
After 24 hours Uptime shows ~24h 0m
After 48 hours Uptime shows ~48h 0m
After 60+ hours Warning log: "App running for 60+ hours"

If App Still Dies

Check 1: Last Logs Before Death

Look at last log entry before silence:

  • If [onAppPaused] present → OS killed app (check device settings)
  • If no lifecycle event → app crashed (check for exceptions)

Check 2: Device-Specific Settings

Some Android devices have aggressive task killers even on AC power:

  • Check "Auto-start" settings (Xiaomi, Oppo, Vivo)
  • Check "Background restrictions" in device settings
  • May need to whitelist app in manufacturer's custom settings

Check 3: Android Version

  • Android 6+ has Doze mode even on AC power
  • Android 9+ has App Standby Buckets
  • May need ADB commands to whitelist:
adb shell dumpsys deviceidle whitelist +com.example.hmg_qline.hmg_qline

Success Indicators

Health check logs every 5 minutes Uptime increments correctly No [onAppPaused] or [onAppDetached] logs Hub connection stays alive App runs past 14-hour mark App runs 48+ hours without restart


Emergency Rollback

If new version causes issues:

  1. Keep old APK as backup
  2. Reinstall old version via ADB
  3. Report issue with last 100 lines of logs