apsl_wallpaper_scheduler
Schedule automatic daily wallpaper updates on Android. Download an image from any URL and set it as the Home Screen, Lock Screen, or Both at an exact time every day — even when the app is closed or the device reboots.
What this package is like to depend on
Last release 4 months ago
24 Apr 2026
Too new to tell
only 2 release windows
Nearly every release is documented
notes for 8 of 8 stable releases
Nothing withdrawn
no release was ever pulled
5 months old
8 releases · first in 2026
8 releases in the last 12 months
see the full history below
Release timeline
8 releases · Mar 2026 to Apr 2026Releases
latest 8-
0.3.024 Apr 2026Release notes
Open source →Reliability overhaul, new configuration options, and reschedule failure notifications
Bug fixes
-
Fixed: scheduler fires only on day 1 and never again. Two root causes fixed: (1)
flutter_local_notificationsinitialize()can hang indefinitely in a background isolate — a 10-second timeout now ensures the reschedule step always runs regardless of notification state. (2)oneShotAt()returnsFuture<bool>—falsemeans Android silently rejected the alarm, but the return value was previously discarded. It is now checked and logged tolastError. -
Fixed: storage failure before reschedule permanently broke the alarm chain. Both
findByAlarmIdcalls in the alarm callback are now wrapped intry-catch. If SharedPreferences throws (storage full, corrupted file, Android I/O error), the first call falls back to a conservative 24-hour reschedule; the second (orphan guard) proceeds with the reschedule rather than silently returning. -
Fixed: orphaned alarm fires forever after a schedule is deleted mid-callback. The record is now re-fetched from storage immediately before rescheduling. If the schedule was deleted or stopped while the download was running, the reschedule is skipped — no ghost alarm is registered.
-
Fixed: multiple schedules with alarm IDs divisible by 10 received 0-second stagger. The stagger formula now combines both parts of the alarm ID so every ID in a typical range maps to a unique delay.
-
Fixed: DST transitions could cause the daily alarm to fire at the wrong time. Reschedule now uses calendar
day + 1construction instead of adding a fixedDuration, so the next fire time is always the correct local calendar day regardless of clocks-forward or clocks-back transitions. -
Fixed: device offline permanently skips wallpaper for the day. On a
[NO_INTERNET]error the next alarm is now scheduled 30 minutes out instead of 24 hours, retrying every 30 minutes until connectivity is restored. -
Fixed: non-image URL (HTML, JSON) passed directly to
setWallpaper. TheContent-Typeresponse header is now validated. A non-image response throws[INVALID_CONTENT_TYPE]with a clear hint instead of a cryptic native failure. -
Fixed: oversized images could crash the background isolate with OOM. Images larger than 20 MB are now rejected with
[IMAGE_TOO_LARGE]before writing to disk. -
Fixed: alarm ID counter had no upper-bound guard. Counter now wraps at 2,000,000,000 to stay within Android's int32 AlarmManager ID space and prevent ID collisions after extended use.
-
Fixed: corrupted
hour/minutevalues in SharedPreferences caused alarms to fire at unexpected times. Values are now clamped to0–23and0–59respectively infromJson. -
Fixed: cache file deletion failures silently accumulate stale files on disk. Deletion errors are now logged via
debugPrintinstead of being swallowed.
New features
-
showErrorNotificationsflag oninitialize(). When set totrue, a local notification is shown whenever the daily alarm reschedule fails — including when Android rejects the alarm (revoked permission), when a storage error is encountered, or whenoneShotAtthrows. The notification body contains the exact, human-readable reason. Defaults tofalse.await ApslWallpaperScheduler.initialize(showErrorNotifications: true); -
validateUrloption onWallpaperScheduleConfig. Whentrue, a HEAD request is sent to the image URL at schedule-creation time to verify it is reachable. Returns aScheduleResult.failureimmediately if the URL returns a non-200 response, rather than discovering the problem days later at alarm fire time. Defaults tofalse. -
Configurable retry count and delay on
WallpaperScheduleConfig.maxRetries(default 2) andretryDelay(default 20 s) are now per-schedule instead of hardcoded, so consumers with slow image servers can increase retries and consumers with fast servers can reduce the delay.WallpaperScheduleConfig( name: 'My Wallpaper', imageUrl: 'https://example.com/image.png', time: const TimeOfDay(hour: 8, minute: 0), validateUrl: true, maxRetries: 4, retryDelay: const Duration(seconds: 10), )
-
-
0.2.521 Apr 2026Release notes
Open source →Reliability & error diagnostics improvements
-
Smarter error logs. Every failure now stores a
[CATEGORY]prefix ([NO_INTERNET],[SERVER_ERROR],[HTTP_404],[DOWNLOAD_TIMEOUT],[CONNECTION_LOST],[WALLPAPER_SET_FAILED], etc.), the attempt number (Attempt 2/3), the server's response body (up to 300 chars — useful when the backend returns a JSON error message), an actionableHint:, and a timestamp. Makes root-cause diagnosis fast without needing device logs. -
Failure push notification. When a wallpaper update fails after all retries, the user now receives a notification with the short error reason instead of silent failure.
-
Increased retry gap and timeout. Retry delay raised from 5 s → 20 s; per-attempt HTTP timeout raised from 30 s → 60 s for better tolerance on slow or unstable connections.
-
SocketException(no internet) now caught and retried. Previously a device with no network at alarm time would produce an unhandled exception that fell through to the outer catch without a structured error message. -
URL validated before any network call. Malformed or non-http(s) URLs are rejected immediately with a clear
[INVALID_URL]message instead of crashing inside the download loop. -
Core wallpaper logic fully isolated from helpers. Storage updates and notifications now run in their own independent
try-catchblocks. A crash in either helper can no longer make a successful wallpaper set appear as a failure, and can no longer prevent tomorrow's alarm from being rescheduled. -
OEM hint on
setWallpaperfailure. When the wallpaper cannot be applied, the error now includes a device-specific hint (MIUI / One UI / ColorOS battery optimisation and "Display over other apps" permission). -
Added
.gitignore. Stops auto-generated files (.dart_tool/,.flutter-plugins-dependencies,local.properties,pubspec.lock) from being tracked in version control.
-
-
0.2.430 Mar 2026Release notes
Open source →Bug fixes
- Fixed: setting wallpaper on "Both Screens" always failed.
Many Android OEM implementations (Samsung One UI, Xiaomi, etc.) do not
reliably honour the combined
FLAG_SYSTEM | FLAG_LOCKbitmask when passed as a singleWallpaperManager.setStream()call, causing it to silently fail. The wallpaper is now applied via two separate calls — one for the Home Screen and one for the Lock Screen — which works correctly across all tested devices. Individual Home Screen and Lock Screen targets are unchanged.
- Fixed: setting wallpaper on "Both Screens" always failed.
Many Android OEM implementations (Samsung One UI, Xiaomi, etc.) do not
reliably honour the combined
-
0.2.330 Mar 2026Release notes
Open source →Bug fixes
- Fixed:
ClientException: connection closed while receiving datanot retried. Addedhttp.ClientExceptionto the retry-eligible exceptions in the image download logic. Previously, if the server dropped the connection mid-transfer, the error propagated immediately with no retry. Now it retries up to 2 times (with a 5-second pause between attempts), consistent with how timeouts and HTTP 5xx errors are handled.
- Fixed:
-
0.2.230 Mar 2026Release notes
Open source →Bug fixes & reliability improvements
-
Fixed: wallpaper stops updating after app is killed and reopened. Added
DartPluginRegistrant.ensureInitialized()in the background alarm callback. Without it, Dart-side plugin registrations (SharedPreferences,path_provider) never ran when the app process was dead, causing the callback to exit silently with no wallpaper update. -
Fixed: wrong wallpaper set when multiple schedules fire at the same time. Each alarm now downloads to its own isolated cache file (
apsl_wallpaper_cache_<alarmId>.png) instead of a single shared file. Previously the last download always overwrote earlier ones, so only one schedule's image was ever applied. -
Fixed: alarm chain could skip a day near midnight.
DateTime.now()is now captured as the very first line of the callback, before anyawait. Previously it was captured after a potentially slow image download, which could drift past midnight and schedule the next alarm two days ahead instead of one. -
Fixed: slow or unreachable server could permanently break the alarm chain. Added a 30-second timeout on every image download. Previously an unresponsive server caused the background isolate to hang indefinitely, blocking the self-reschedule step that maintains the daily chain.
-
Fixed: uncaught exception in self-reschedule permanently broke the alarm chain. The
AndroidAlarmManager.oneShotAtcall is now wrapped in its owntry-catch. Any failure is recorded inlastErrorand the chain survives. -
Fixed: JSON corruption silently wiped all schedules.
ScheduleStoragenow writes the current valid snapshot as a backup key before every save. On next load, if the primary entry is corrupt, it automatically recovers from the backup instead of returning an empty list. -
Fixed: invalid image URLs only discovered at alarm fire time (hours later).
createScheduleandupdateSchedulenow validate the URL immediately — must be non-empty and start withhttp://orhttps://. A clear error is returned at creation time instead of a silent failure during the background alarm callback.
New features
-
Retry on server errors. The image download now retries up to 2 times (with a 5-second pause between attempts) when the server returns an HTTP 5xx error or the request times out. 4xx errors (bad URL, not found) are not retried. This makes background updates resilient to transient server issues.
-
Stagger for same-time schedules. Each alarm callback now waits
(alarmId % 10) × 2seconds (0–18 s) before making its HTTP request. When multiple schedules are set to the same time, their requests are spread out so the image server never receives simultaneous hits, preventing the rate-limiting HTTP 500 errors that caused one of every two same-time schedules to fail. -
Cache cleanup. The per-alarm image cache file is always deleted after
setWallpapercompletes (success or failure), preventing stale files from accumulating in the app's documents directory.
-
-
0.2.130 Mar 2026Release notes
Open source →requestBatteryOptimizationExemption()now returnsFuture<bool>instead ofFuture<void>.- Returns
trueif the battery-optimisation exemption is (or was already) granted,falseif the user declined. - Allows callers to react immediately to the user's decision without a follow-up
checkPermissions()call.
- Returns
-
0.2.027 Mar 2026Release notes
Open source →- Bumped dependency versions for compatibility with modern Flutter apps:
flutter_local_notificationsupgraded from^17.2.2to^19.5.0.permission_handlerupgraded from^11.3.1to^12.0.0+1.shared_preferencesupgraded from^2.2.3to^2.5.3.path_providerupgraded from^2.1.2to^2.1.5.httpupgraded from^1.2.1to^1.2.2.
- Bumped dependency versions for compatibility with modern Flutter apps:
-
0.1.027 Mar 2026Release notes
Open source →- Initial release.
createSchedule— create and activate a daily wallpaper schedule.updateSchedule— edit an existing schedule.deleteSchedule/deleteAllSchedules— remove schedules.startSchedule/stopSchedule— toggle a schedule on/off.getAllSchedules/getActiveSchedules/getSchedule— query schedules.- Permission helpers:
requestExactAlarmPermission,requestBatteryOptimizationExemption. - Uses
setExactAndAllowWhileIdlefor truly exact daily alarms. - Survives app kill and device reboots via
rescheduleOnReboot.