diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart
index 44d370e59..e3822ae2d 100644
--- a/cw_core/lib/wallet_base.dart
+++ b/cw_core/lib/wallet_base.dart
@@ -60,6 +60,8 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
 
   bool get isHardwareWallet => walletInfo.isHardwareWallet;
 
+  Future<void> init();
+
   Future<void> connectToNode({required Node node});
 
   // there is a default definition here because only coins with a pow node (nano based) need to override this
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index dc3efcb91..f4ecb9014 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -158,10 +158,7 @@ abstract class MoneroWalletBase
       }
     }
 
-    // TODO: this doesn't work, need to find a better way to check if we are on the main thread
-    bool isMainThread = Isolate.current.debugName == "main";
-    printV("isMainThread: $isMainThread");
-
+    _autoSaveTimer?.cancel();
     _autoSaveTimer =
         Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
 
@@ -275,6 +272,8 @@ abstract class MoneroWalletBase
       return;
     }
     monero_wallet.stopSync();
+    _autoSaveTimer?.cancel();
+    monero_wallet.closeCurrentWallet();
   }
 
   @override
@@ -737,13 +736,17 @@ abstract class MoneroWalletBase
       if (walletInfo.isRecovery) {
         await _askForUpdateTransactionHistory();
         _askForUpdateBalance();
-        walletAddresses.accountList.update();
+        if (!isBackgroundSyncing) {
+          walletAddresses.accountList.update();
+        }
       }
 
       if (blocksLeft < 100) {
         await _askForUpdateTransactionHistory();
         _askForUpdateBalance();
-        walletAddresses.accountList.update();
+        if (!isBackgroundSyncing) {
+          walletAddresses.accountList.update();
+        }
         syncStatus = SyncedSyncStatus();
 
         if (!_hasSyncAfterStartup) {
diff --git a/lib/entities/background_tasks.dart b/lib/entities/background_tasks.dart
index b5416962e..1ca9a1536 100644
--- a/lib/entities/background_tasks.dart
+++ b/lib/entities/background_tasks.dart
@@ -118,6 +118,22 @@ void setWalletNotification(FlutterLocalNotificationsPlugin flutterLocalNotificat
   );
 }
 
+AppLifecycleState appStateFromString(String state) {
+  switch (state) {
+    case "AppLifecycleState.paused":
+      return AppLifecycleState.paused;
+    case "AppLifecycleState.resumed":
+      return AppLifecycleState.resumed;
+    case "AppLifecycleState.hidden":
+      return AppLifecycleState.hidden;
+    case "AppLifecycleState.detached":
+      return AppLifecycleState.detached;
+    case "AppLifecycleState.inactive":
+      return AppLifecycleState.inactive;
+  }
+  throw Exception("unknown app state: $state");
+}
+
 @pragma("vm:entry-point")
 Future<void> onStart(ServiceInstance service) async {
   printV("BACKGROUND SERVICE STARTED");
@@ -125,10 +141,13 @@ Future<void> onStart(ServiceInstance service) async {
   Timer? _syncTimer;
   Timer? _stuckSyncTimer;
   Timer? _queueTimer;
+  Timer? _appStateTimer;
   List<WalletBase> syncingWallets = [];
   List<WalletBase> standbyWallets = [];
   Timer? _bgTimer;
-  int fgCount = 0;
+  AppLifecycleState lastAppState = AppLifecycleState.resumed;
+  final List<AppLifecycleState> lastAppStates = [];
+  String serviceState = "NOT_RUNNING";
 
   // commented because the behavior appears to be bugged:
   // DartPluginRegistrant.ensureInitialized();
@@ -136,8 +155,7 @@ Future<void> onStart(ServiceInstance service) async {
   final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
       FlutterLocalNotificationsPlugin();
 
-  service.on("stopService").listen((event) async {
-    printV("STOPPING BACKGROUND SERVICE");
+  Future<void> stopAllSyncing() async {
     _syncTimer?.cancel();
     _stuckSyncTimer?.cancel();
     _queueTimer?.cancel();
@@ -157,6 +175,11 @@ Future<void> onStart(ServiceInstance service) async {
     } catch (e) {
       printV("error stopping sync: $e");
     }
+  }
+
+  service.on("stopService").listen((event) async {
+    printV("STOPPING BACKGROUND SERVICE");
+    await stopAllSyncing();
     // stop the service itself:
     service.invoke("serviceState", {"state": "NOT_RUNNING"});
     await service.stopSelf();
@@ -166,36 +189,39 @@ Future<void> onStart(ServiceInstance service) async {
     printV(event);
   });
 
-  void setForeground() {
+  Future<void> setForeground() async {
+    serviceState = "FOREGROUND";
     bgSyncStarted = false;
-    _syncTimer?.cancel();
     setNotificationStandby(flutterLocalNotificationsPlugin);
   }
 
   service.on("setForeground").listen((event) async {
-    setForeground();
+    await setForeground();
     service.invoke("serviceState", {"state": "FOREGROUND"});
   });
 
   void setReady() {
-    setNotificationReady(flutterLocalNotificationsPlugin);
+    if (serviceState != "READY" && serviceState != "BACKGROUND") {
+      serviceState = "READY";
+      setNotificationReady(flutterLocalNotificationsPlugin);
+    }
   }
 
   service.on("setReady").listen((event) async {
     setReady();
-    service.invoke("serviceState", {"state": "READY"});
   });
 
-  service.on("foregroundPing").listen((event) async {
-    fgCount = 0;
+  service.on("appState").listen((event) async {
+    printV("APP STATE: ${event?["state"]}");
+    lastAppState = appStateFromString(event?["state"] as String);
   });
 
   // we have entered the background, start the sync:
   void setBackground() async {
-    if (bgSyncStarted) {
-      return;
-    }
+    // only runs once per service instance:
+    if (bgSyncStarted) return;
     bgSyncStarted = true;
+    serviceState = "BACKGROUND";
 
     await Future.delayed(const Duration(seconds: DELAY_SECONDS_BEFORE_SYNC_START));
     printV("STARTING SYNC FROM BG");
@@ -482,23 +508,24 @@ Future<void> onStart(ServiceInstance service) async {
     setBackground();
   });
 
-  // this is a backup timer to trigger in case the user fully closes the app, so that we still
-  // start the background sync process:
-  // annoyingly foreground code still runs in the background on android for some time, so we still use the original method
-  // to detect if we are in the background since it's much faster
-  _bgTimer = Timer.periodic(const Duration(seconds: 1), (timer) async {
-    fgCount++;
-    // we haven't been pinged in a while, so we are likely in the background:
-    if (fgCount == 4) {
-      setReady();
-      return;
+  // if the app state changes to paused, setReady()
+  // if the app state has been paused for more than 10 seconds, setBackground()
+  _appStateTimer = Timer.periodic(const Duration(seconds: 1), (timer) async {
+    lastAppStates.add(lastAppState);
+    if (lastAppStates.length > 10) {
+      lastAppStates.removeAt(0);
     }
-
-    if (fgCount > 10) {
-      fgCount = 0;
+    // printV(lastAppStates);
+    // if (lastAppState == AppLifecycleState.resumed && serviceState != "FOREGROUND") {
+    //   setForeground();
+    // }
+    if (lastAppStates.length < 5) return;
+    if (lastAppState == AppLifecycleState.paused && serviceState != "READY") {
+      setReady();
+    }
+    // if all 10 states are paused, setBackground()
+    if (lastAppStates.every((state) => state == AppLifecycleState.paused) && !bgSyncStarted) {
       setBackground();
-      service.invoke("serviceState", {"state": "BACKGROUND"});
-      _bgTimer?.cancel();
     }
   });
 }
@@ -592,16 +619,22 @@ class BackgroundTasks {
     bgService.invoke("foregroundPing");
   }
 
-  Future<void> serviceForeground() async {
-    if (serviceState == "FOREGROUND") {
-      return;
-    }
+  void lastAppState(AppLifecycleState state) {
+    bgService.invoke("appState", {"state": state.toString()});
+  }
 
+  Future<void> serviceForeground() async {
+    printV("SERVICE FOREGROUNDED");
     final settingsStore = getIt.get<SettingsStore>();
     bool showNotifications = settingsStore.showSyncNotification;
     bgService.invoke("stopService");
-    await Future.delayed(const Duration(seconds: 2));
+    await Future.delayed(const Duration(seconds: 3));
     initializeService(bgService, showNotifications);
+    bgService.invoke("setForeground");
+  }
+
+  Future<bool> isServiceRunning() async {
+    return await bgService.isRunning();
   }
 
   void serviceReady() {
diff --git a/lib/src/screens/root/root.dart b/lib/src/screens/root/root.dart
index 95313d386..53005c63d 100644
--- a/lib/src/screens/root/root.dart
+++ b/lib/src/screens/root/root.dart
@@ -133,7 +133,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
   }
 
   @override
-  void didChangeAppLifecycleState(AppLifecycleState state) {
+  void didChangeAppLifecycleState(AppLifecycleState state) async {
     final syncingWalletTypes = [WalletType.litecoin, WalletType.monero, WalletType.bitcoin];
     switch (state) {
       case AppLifecycleState.paused:
@@ -145,10 +145,6 @@ class RootState extends State<Root> with WidgetsBindingObserver {
           setState(() => _setInactive(true));
         }
 
-        if (FeatureFlag.isBackgroundSyncEnabled && syncingWalletTypes.contains(widget.appStore.wallet?.type)) {
-          widget.appStore.wallet?.stopSync();
-        }
-
         break;
       case AppLifecycleState.resumed:
         widget.authService.requireAuth().then((value) {
@@ -163,37 +159,53 @@ class RootState extends State<Root> with WidgetsBindingObserver {
         break;
     }
 
+    // _stateTimer?.cancel();
+    // _stateTimer = Timer(const Duration(seconds: 1), () async {
+    //   getIt.get<BackgroundTasks>().lastAppState(state);
+    // });
+
+    getIt.get<BackgroundTasks>().lastAppState(state);
+
     // background service handling:
+    printV("state: $state");
     switch (state) {
       case AppLifecycleState.resumed:
-        // restart the background service if it was running before:
-        getIt.get<BackgroundTasks>().serviceForeground();
-        _stateTimer?.cancel();
-        if (!wasInBackground) {
-          return;
-        }
-        wasInBackground = false;
-        if (syncingWalletTypes.contains(widget.appStore.wallet?.type)) {
-          // wait a few seconds before starting the sync make sure the background service is fully exited:
-          Future.delayed(const Duration(seconds: 3), () {
-            widget.appStore.wallet?.startSync();
-          });
-        }
+        // // restart the background service if it was running before:
+        await getIt.get<BackgroundTasks>().serviceForeground();
+        // _stateTimer?.cancel();
+        // if (!wasInBackground) {
+        //   return;
+        // }
+        // wasInBackground = false;
+        // final appStore = widget.appStore;
+        // final wallet = appStore.wallet;
+        // if (syncingWalletTypes.contains(wallet?.type)) {
+        //   // wait a few seconds before starting the sync to make sure the background service is fully exited:
+        //   Future.delayed(const Duration(seconds: 50), () async {
+        //     final node = appStore.settingsStore.getCurrentNode(wallet!.type);
+        //     await wallet.stopSync();
+        //     await wallet.init();
+        //     wallet.connectToNode(node: node);
+        //     wallet.startSync();
+        //   });
+        // }
         break;
-      case AppLifecycleState.paused:
-        getIt.get<BackgroundTasks>().serviceReady();
+      case AppLifecycleState.hidden:
       case AppLifecycleState.inactive:
       case AppLifecycleState.detached:
-      default:
-        // anything other than resumed update the notification to say we're in the "ready" state:
-        // if we enter any state other than resumed start a timer for 30 seconds
-        // after which we'll consider the app to be in the background
-        _stateTimer?.cancel();
-        // TODO: bump this to > 30 seconds when testing is done:
-        _stateTimer = Timer(const Duration(seconds: 10), () async {
-          wasInBackground = true;
-          getIt.get<BackgroundTasks>().serviceBackground();
-        });
+        break;
+      case AppLifecycleState.paused:
+        widget.appStore.wallet?.stopSync();
+        // getIt.get<BackgroundTasks>().serviceReady();
+        // // if (FeatureFlag.isBackgroundSyncEnabled &&
+        // //     syncingWalletTypes.contains(widget.appStore.wallet?.type)) {
+        // //   widget.appStore.wallet?.stopSync();
+        // // }
+        // _stateTimer?.cancel();
+        // _stateTimer = Timer(const Duration(seconds: 10), () async {
+        //   wasInBackground = true;
+        //   getIt.get<BackgroundTasks>().serviceBackground();
+        // });
         break;
     }
     _previousState = state;