A photo-shuffle live wallpaper for Android, in the spirit of iOS Photo Shuffle. Pick folders of photos and it swaps your wallpaper on tap, on lock, hourly, daily or on your own interval.
It works on any Android phone or tablet. On foldables (Galaxy Z Fold and Z Flip, Pixel Fold and others) it goes further: the cover screen and the main screen each get their own photo, and it can change the photo every time you fold or unfold.
Formerly FoldShuffle.
- Set live wallpaper button that opens the system preview; apply it to home, lock, or both.
- Photo folders through Android's folder picker, with no storage permission. Subfolders are optional, and only new or changed files are re-read.
- Change photo: on tap (double-tap empty home-screen space), on lock (a new photo is waiting when the screen comes back on), hourly (on the hour), daily (at midnight), or every N minutes.
- Order: shuffle with no repeats until every photo has been shown, or go in order.
- Smart fit: Off, Prefer or Strict. Photos shaped like the screen come first.
- Look: Fill (with parallax across home pages), Fit with a blurred backdrop, or Fit on black; a 0–2 s crossfade; dimming on the lock screen (Android 14+).
- Quick Settings tile "Shuffle wallpaper" for a one-tap next photo.
- Survives reboots and storage hiccups. Each screen's current photo is cached privately and shown instantly on a cold start. A photo that can't be read is retried, never deleted.
- The cover and main screens each have their own shuffle; each folder can feed cover, main or both.
- Change on fold / unfold, or "also change on fold" alongside any other schedule.
- Keep screens in sync: show the same photo on both when it belongs to both pools.
- Smart fit sends tall photos to a Fold's narrow cover and wider ones to its main screen.
Foldables are detected automatically, from the hinge sensor or from seeing two screen shapes. You can also pick Single, Fold or Flip under Screens.
Android presents a foldable's two panels as one display that changes size when the hinge moves, so the wallpaper engine sees a surface resize. Panels are told apart by shape, because a resolution change keeps the shape and a different panel doesn't. Once both are known, the smaller one is the cover screen. On a single-screen device everything is the main screen.
The screen in use is the one whose engine is visible, not the one that last resized. A Pixel Fold resizes one engine when it folds; a Galaxy Z Fold keeps an engine for each screen and shows one while hiding the other, so it never resizes anything.
Engines are views of one shared state, so home, lock and preview engines stay consistent, and the app and the tile can drive them. A failed load never removes anything. If the photo's folder can't be read, the screen keeps its photo and the load retries with backoff. This matters right after a reboot, when Android's file provider refuses reads for a few seconds.
Gradle 9 + AGP 9.3.1 (Kotlin is built into AGP 9; do not apply the Kotlin Android plugin).
gradle testDebugUnitTest # unit tests
gradle assembleDebug # app/build/outputs/apk/debug/app-debug.apk
./tools/make-keystore.sh # once; the keystore is gitignored, back it up
gradle assembleRelease # app/build/outputs/apk/release/app-release.apk (R8, ~2 MB)minSdk 29, targetSdk 35. No network access, no analytics, no runtime permissions.
Any phone AVD covers the single-screen path. For foldables, the pixel_fold AVD profile with the
API 34 Google APIs image supports real fold states:
avdmanager create avd -n fold -k "system-images;android-34;google_apis;arm64-v8a" -d pixel_fold
emulator -avd fold -no-window -gpu swiftshader_indirect
adb emu fold # display becomes 1080x2092 -> "surface ... -> COVER"
adb emu unfold # 2208x1840 -> "surface ... -> MAIN"Watch adb logcat -s WallpaperShuffle for surfaces, screen switches, load retries and scans.
Without adb, Screens → Copy screen log copies the device details, the screen sizes seen and
recent surface and visibility events from each engine.