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.
How It Works
Section titled “How It Works”Architecture
Section titled “Architecture”The task scheduling system bridges Flutter and native Android:
- Flutter side: The
TaskSchedulerServicecommunicates via the method channelcom.affluentlabs.zestssh/scheduler. - Native side: Android WorkManager enqueues and executes the scheduled work.
- 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.
Available on Android Only
Section titled “Available on Android Only”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.
Scheduling Tasks
Section titled “Scheduling Tasks”Recurring Tasks
Section titled “Recurring Tasks”TaskSchedulerService.scheduleRecurring( taskId: 'daily-backup-check', action: 'execute', connectionId: 'server-abc', command: '/opt/scripts/backup-check.sh', apiKeyId: 'key-123', intervalMinutes: 1440, // 24 hours)| Parameter | Description |
|---|---|
taskId | Unique identifier for the scheduled task |
action | Action type: execute, snippet, connect, workflow |
connectionId | Target connection to run against |
command | Shell command to execute (for execute action) |
apiKeyId | ID of the automation API key (looked up from secure storage at runtime) |
intervalMinutes | Repeat interval (minimum 15 minutes — WorkManager constraint) |
initialDelayMinutes | Delay before the first execution |
snippetName | Snippet name (for snippet action) |
workflowId / workflowName | Workflow identifier (for workflow action) |
One-Shot Tasks
Section titled “One-Shot Tasks”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.
Task Management
Section titled “Task Management”| Operation | Method |
|---|---|
| Schedule recurring | scheduleRecurring() |
| Schedule one-shot | scheduleOneShot() |
| Cancel a task | cancelTask(taskId) |
| Cancel all tasks | cancelAll() |
| Check if task is scheduled | isScheduled(taskId) |
Foreground Service
Section titled “Foreground Service”For active SSH connections (not background automation), ZestSSH uses an Android foreground service to keep connections alive when the app is backgrounded.
How It Works
Section titled “How It Works”The ForegroundService class communicates via method channel com.affluentlabs.zestssh/foreground:
| Method | Purpose |
|---|---|
startService | Start the foreground service with a connection count |
updateCount | Update the notification to reflect current active connections |
stopService | Stop 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.
Notification
Section titled “Notification”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.
Battery Optimization
Section titled “Battery Optimization”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.
Standard Android (AOSP)
Section titled “Standard Android (AOSP)”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).
Recommended Setting
Section titled “Recommended Setting”Exclude ZestSSH from battery optimization:
- Go to Android Settings > Apps > ZestSSH > Battery.
- Select Unrestricted (or disable battery optimization for this app).
OEM-Specific Issues
Section titled “OEM-Specific Issues”Several Android manufacturers add aggressive battery management on top of stock Android. These can kill background tasks and foreground services.
Xiaomi / MIUI / HyperOS
Section titled “Xiaomi / MIUI / HyperOS”Xiaomi devices are the most aggressive. Required settings:
- Settings > Apps > Manage apps > ZestSSH > Battery Saver: Set to “No restrictions”.
- Settings > Battery & performance > App battery saver: Find ZestSSH, set to “No restrictions”.
- Security app > Permissions > Autostart: Enable ZestSSH.
- 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 / One UI
Section titled “Samsung / One UI”Samsung’s device maintenance can terminate background processes:
- Settings > Battery > Battery usage > More battery settings: Disable “Adaptive battery” or add ZestSSH to the “Never sleeping” list.
- Settings > Apps > ZestSSH > Battery: Set to “Unrestricted”.
- Settings > Device care > Battery > Background usage limits: Ensure ZestSSH is not in the “Sleeping” or “Deep sleeping” lists.
Huawei / EMUI
Section titled “Huawei / EMUI”- Settings > Battery > App launch: Find ZestSSH, disable automatic management and enable all three toggles (Auto-launch, Secondary launch, Run in background).
- Settings > Apps > ZestSSH > Battery: Allow background activity.
OnePlus / OxygenOS
Section titled “OnePlus / OxygenOS”- Settings > Battery > Battery Optimization: Find ZestSSH, select “Don’t optimize”.
- Settings > Apps & notifications > Advanced > Special app access > Battery optimization: Exclude ZestSSH.
General Advice
Section titled “General Advice”If automation tasks are not firing reliably:
- Check the Automation History to see if tasks ran at all.
- Exclude ZestSSH from all battery optimization.
- On devices with aggressive OEM software, lock the app in recents.
- 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.