Skip to content

Android Background Automation

ZestSSH uses Android’s WorkManager to schedule and execute background automation tasks — running SSH commands, snippets, and workflows on a schedule without user interaction.

The task scheduling system bridges Flutter and native Android:

  1. Flutter side: The TaskSchedulerService communicates via the method channel com.affluentlabs.zestssh/scheduler.
  2. Native side: Android WorkManager enqueues and executes the scheduled work.
  3. Execution: When a task fires, the native worker sends an automation intent back to the Flutter side, which connects to the target server, runs the command, and logs the result.

TaskSchedulerService.isAvailable returns true only on Android. On iOS, users are directed to use iOS Shortcuts Automations instead. On desktop platforms, the service is a no-op.

TaskSchedulerService.scheduleRecurring(
taskId: 'daily-backup-check',
action: 'execute',
connectionId: 'server-abc',
command: '/opt/scripts/backup-check.sh',
apiKeyId: 'key-123',
intervalMinutes: 1440, // 24 hours
)
ParameterDescription
taskIdUnique identifier for the scheduled task
actionAction type: execute, snippet, connect, workflow
connectionIdTarget connection to run against
commandShell command to execute (for execute action)
apiKeyIdID of the automation API key (looked up from secure storage at runtime)
intervalMinutesRepeat interval (minimum 15 minutes — WorkManager constraint)
initialDelayMinutesDelay before the first execution
snippetNameSnippet name (for snippet action)
workflowId / workflowNameWorkflow identifier (for workflow action)

For single-execution tasks with a delay, use scheduleOneShot:

  • Same parameters as recurring, but runs only once.
  • Useful for delayed command execution or one-time maintenance tasks.
OperationMethod
Schedule recurringscheduleRecurring()
Schedule one-shotscheduleOneShot()
Cancel a taskcancelTask(taskId)
Cancel all taskscancelAll()
Check if task is scheduledisScheduled(taskId)

For active SSH connections (not background automation), ZestSSH uses an Android foreground service to keep connections alive when the app is backgrounded.

The ForegroundService class communicates via method channel com.affluentlabs.zestssh/foreground:

MethodPurpose
startServiceStart the foreground service with a connection count
updateCountUpdate the notification to reflect current active connections
stopServiceStop the service when no connections remain

The native service holds a persistent notification (required by Android for foreground services). The Dart isolate handles all actual SSH traffic.

While connections are active, a persistent notification shows the number of active SSH sessions. This is required by Android — foreground services must display an ongoing notification.

Android’s battery optimization can interfere with both WorkManager tasks and the foreground service. ZestSSH works within these constraints but certain OEM customizations can cause issues.

On stock Android, WorkManager tasks are subject to:

  • Doze mode: Tasks may be deferred when the device is idle.
  • App Standby Buckets: Infrequent tasks may be batched.
  • 15-minute minimum interval: WorkManager enforces this as the shortest repeat period.

The foreground service is not affected by Doze mode (it holds a wakelock via the persistent notification).

Exclude ZestSSH from battery optimization:

  1. Go to Android Settings > Apps > ZestSSH > Battery.
  2. Select Unrestricted (or disable battery optimization for this app).

Several Android manufacturers add aggressive battery management on top of stock Android. These can kill background tasks and foreground services.

Xiaomi devices are the most aggressive. Required settings:

  1. Settings > Apps > Manage apps > ZestSSH > Battery Saver: Set to “No restrictions”.
  2. Settings > Battery & performance > App battery saver: Find ZestSSH, set to “No restrictions”.
  3. Security app > Permissions > Autostart: Enable ZestSSH.
  4. Lock the app in recents: Open ZestSSH in the recent apps view, swipe down on the card to lock it (shows a padlock icon).

Samsung’s device maintenance can terminate background processes:

  1. Settings > Battery > Battery usage > More battery settings: Disable “Adaptive battery” or add ZestSSH to the “Never sleeping” list.
  2. Settings > Apps > ZestSSH > Battery: Set to “Unrestricted”.
  3. Settings > Device care > Battery > Background usage limits: Ensure ZestSSH is not in the “Sleeping” or “Deep sleeping” lists.
  1. Settings > Battery > App launch: Find ZestSSH, disable automatic management and enable all three toggles (Auto-launch, Secondary launch, Run in background).
  2. Settings > Apps > ZestSSH > Battery: Allow background activity.
  1. Settings > Battery > Battery Optimization: Find ZestSSH, select “Don’t optimize”.
  2. Settings > Apps & notifications > Advanced > Special app access > Battery optimization: Exclude ZestSSH.

If automation tasks are not firing reliably:

  1. Check the Automation History to see if tasks ran at all.
  2. Exclude ZestSSH from all battery optimization.
  3. On devices with aggressive OEM software, lock the app in recents.
  4. Consider using the foreground service (keep a connection open) to prevent the system from killing the process.

For a comprehensive database of OEM battery restrictions, visit Don’t Kill My App.