An Android TV screensaver app for the Huawei TV Stick, Amazon Fire TV Stick, and any Android TV device. Choose between a photo slideshow (Google Drive, OneDrive, Dropbox, Immich, Nextcloud, Synology NAS, or device storage) or a fullscreen music visualizer — the perfect companion for listening to music on your TV. Put on some music, let the screen go idle, and AndroSaver turns your TV into an audio-reactive light show that pulses and morphs in real time.
Two brand-new visualizer effects and a full visual overhaul:
- Aurora — Northern Lights curtains sweep across the screen. Five sinusoidal ribbons with three overlapping harmonics each produce genuinely organic, ever-shifting curtain motion. Bass billows the ribbons; treble drives shimmer speed; beats fire a bloom flash. Drawn with additive blend so overlapping curtains glow brighter together.
- Lattice — A 14×9 crystal grid of glowing nodes wired together by double-stroke beam lines. Each column maps to a different FFT frequency bin, so the grid lights up from left (bass) to right (treble) as the music plays. On every strong beat a shockwave ring expands from the centre and flares every node it touches white-hot.
- Bloom post-processing — every frame is composited through a 2-pass Gaussian blur at half resolution and added back onto the screen, giving neon glow to all 18 effects without per-mode changes.
- Butterflies wander breaks — paired butterflies now periodically break from their mutual orbit and wander freely before resuming the chase, making long sessions much more varied.
- Genre-driven auto-switching — when Genre is set to Auto-detect, the app switches visualizer style every 30 seconds to match the detected music genre (electronic, rock, classical).
- Google Drive source — streams photos from a Drive folder using OAuth 2.0 device flow (no Google Play Services required)
- OneDrive source — streams photos from Microsoft OneDrive using OAuth 2.0 device flow; works with personal and work/school accounts
- Dropbox source — streams photos from a Dropbox folder via OAuth 2.0 authorization code flow; access token auto-refreshed using App Key + App Secret
- Immich source — streams photos from a self-hosted Immich server via its REST API; API key auth; optional album filter
- Nextcloud source — streams photos from any folder via WebDAV; works with app passwords and self-signed certificates
- Synology NAS source — streams photos from any FileStation folder via the Synology DSM REST API; session re-authenticated automatically every 25 minutes
- Device storage source — uses photos from the TV's local storage via MediaStore
- All sources can be active simultaneously; images are merged and shuffled
- Offline cache — up to 200 images / 300 MB stored locally; used automatically as a fallback when sources are unreachable
- Six transition effects: Crossfade, Fade to Black, Slide Left, Slide Right, Zoom In, Zoom Out, plus a Random mode
- Configurable time per image (5 s – 30 min) and transition speed (1 – 5 seconds)
- Ken Burns effect — slow pan and zoom animation; each photo always comes to rest centered
- EXIF orientation — portrait photos from phones are displayed upright regardless of source
- Visualizer overlay — music visualizer rendered semi-transparently on top of the slideshow
Designed for listening sessions: start playing music in any app, let the screen idle, and AndroSaver takes over with a fullscreen light show that reacts to every beat.
- Eighteen audio-reactive OpenGL ES 2.0 effects: Yantra, Cube, TriFlux, Lissajous, Tunnel, Corridor, Nova, Spiral, Bubbles, Plasma, Branches, Butterflies, FlowField, Vortex, Aurora, Lattice, Spectrum, Waterfall
- Reacts to system audio — works with any music or streaming app on the TV
- Remote control — use the TV remote while the visualizer is running:
- ← / → — previous / next visual effect
- ↑ / ↓ — increase / decrease beat-response intensity (5 steps: Off → Subtle → Normal → High → Intense)
- Any other key — dismiss the screensaver
- Music Genre hint — tunes the beat-detection frequency weighting to the music style (Any / Electronic / Rock / Classical); see genre hint details below
- Auto-cycle mode rotates through all effects on a configurable interval (off by default)
- Configurable effect and intensity via Settings
- Remote control while slideshow is running:
- → — skip to next image immediately
- ← — go back to previous image
- Any other key — dismiss the screensaver
- Clock overlay — date and time shown in the corner (available in both Slideshow and Visualizer mode)
- Weather widget — current temperature and conditions from OpenWeatherMap (available in both modes)
- Schedule — restrict the screensaver to a configurable active time window (e.g. 08:00–22:00)
- Preview mode — test the screensaver from the Settings app without activating the system screensaver
- In-app updater — checks GitHub Releases on each Settings open; prompts to install if a newer build is available; update channel (Stable / Dev) selectable in Settings
- Registered as a system Dream Service — appears in Android TV's screensaver settings
The easiest way to install on an Amazon Fire TV or Android TV device is via the Downloader app:
| Release | Downloader code | Short URL | Notes |
|---|---|---|---|
| Stable | 7582483 |
aftv.news/7582483 | No debug logging |
| Dev | 9149021 |
aftv.news/9149021 | Debug logging enabled |
- Install Downloader from the Amazon Appstore or Google Play.
- Open Downloader and enter the code (or short URL) for the version you want.
- Follow the on-screen prompts to install the APK.
- Android 5.0+ (API 21)
- Any Android device — optimised for Android TV (tested on Huawei TV Stick and Amazon Fire TV Stick), also works on tablets and phones
- Android Studio Hedgehog or later (to build from source)
RECORD_AUDIOpermission required for the Music Visualizer (prompted automatically when you select Visualizer mode in Settings)READ_MEDIA_IMAGES/READ_EXTERNAL_STORAGEpermission required for the Device Photos source (prompted when you enable the toggle)
- Clone the repo and open it in Android Studio.
- Android Studio will download the Gradle wrapper automatically on first sync.
- Select the build variant in Build > Select Build Variant:
devRelease— debug logging enabled (mirrors the Dev APK)prodRelease— no debug logging (mirrors the Stable APK)
- Build and install via
Run > Run 'app'oradb install.
Google's device-auth flow works without Google Play Services, making it ideal for Huawei devices.
- Go to Google Cloud Console and create a project.
- Enable the Google Drive API.
- Create OAuth 2.0 credentials — choose application type "TV and Limited Input Devices".
- Open the AndroSaver Settings app on your TV.
- Tap Google Drive Setup and enter:
- OAuth Client ID — from your Google Cloud project
- OAuth Client Secret — from your Google Cloud project
- Folder ID (optional) — leave blank to use the root of My Drive
- Tap Authorize with Google — the screen displays a short code and a URL.
- On any other device, visit the URL and enter the code.
- Return to Settings and enable the Google Drive toggle.
Getting a Folder ID: Open Google Drive in a browser, navigate to the folder, and copy the ID from the URL (
/drive/folders/<FOLDER_ID>).
Microsoft's device auth flow works without a browser redirect, making it ideal for Android TV.
- Go to portal.azure.com and sign in.
- Open Azure Active Directory → App registrations → New registration.
- Give it any name; under Supported account types select Accounts in any organizational directory and personal Microsoft accounts.
- Under Authentication → Platform configurations, add Mobile and desktop applications.
- Still under Authentication, enable Allow public client flows.
- Copy the Application (client) ID.
- Open AndroSaver Settings on your TV.
- Tap OneDrive Setup and enter:
- Client ID — the Application (client) ID from step 6
- Folder Path (optional) — leave blank for root, or enter e.g.
/Photos
- Tap Authorize with Microsoft — the screen shows a URL and a short code.
- On any other device, visit the URL and enter the code.
- Return to Settings and enable the OneDrive toggle.
- Go to dropbox.com/developers → App Console → Create app.
- Set access to Full Dropbox (or App folder if you prefer).
- From the app's Settings tab, copy the App Key and App Secret.
- Open AndroSaver Settings on your TV.
- Tap Image Sources → Dropbox Setup and enter:
- App Key and App Secret from step 3
- Folder Path (optional) — leave blank for root, or enter e.g.
/Photos
- Tap Authorize with Dropbox — the screen displays a URL.
- On any other device, visit the URL and sign in to Dropbox.
- Dropbox shows a short code — paste it back into the TV and tap Submit Code.
- Return to Settings and enable the Dropbox toggle.
Access tokens are refreshed automatically using the App Key + App Secret; no re-authorization is needed unless you revoke the app.
-
In Immich web UI, go to Account Settings → API Keys and create a new key.
-
Open AndroSaver Settings on your TV.
-
Tap Immich Setup and fill in:
Field Description Host / IP e.g. 192.168.1.50orphotos.example.comPort 2283(default) or443(HTTPS)Use HTTPS Enable if your Immich instance uses HTTPS (self-signed certs are accepted) API Key The key generated in Immich Account Settings Album ID Optional — paste an album UUID to show only that album; leave blank for all photos -
Tap Test Connection to verify, then Save and enable the Immich toggle in Settings.
To get an album's UUID: open the album in Immich and copy the UUID from the URL (
/albums/<uuid>).
-
Open AndroSaver Settings on your TV.
-
Tap Nextcloud Setup and fill in:
Field Description Host / IP e.g. cloud.example.comor192.168.1.50Port 443(HTTPS) or80(HTTP)Use HTTPS Enable for HTTPS (self-signed certs are accepted) Username Your Nextcloud username Password / App Password Your Nextcloud password, or an app password from Nextcloud's Security settings Image Folder Path e.g. /Photosor/family/Pictures -
Tap Test Connection to verify — a success message shows how many images were found.
-
Tap Save, then enable the Nextcloud toggle in Settings.
App passwords are recommended: in Nextcloud, go to Settings → Security → Devices & Sessions → Create new app password.
-
Open AndroSaver Settings on your TV.
-
Tap Synology NAS Setup and fill in:
Field Description Host / IP e.g. 192.168.1.100ornas.localPort 5000(HTTP) or5001(HTTPS)Use HTTPS Enable if your DSM uses HTTPS (self-signed certs are accepted for local use) Username A DSM account with FileStation access Password DSM account password Image Folder Path e.g. /photosor/homes/alice/Pictures -
Tap Test Connection to verify — a success message shows how many images were found.
-
Tap Save, then enable the Synology NAS toggle in Settings.
| Source | Formats |
|---|---|
| Google Drive | Any format with an image/ MIME type |
| OneDrive | Any format with an image/ MIME type |
| Dropbox | Any format supported by Glide (JPEG, PNG, WebP, GIF, HEIC, BMP) |
| Immich | Any IMAGE type asset (as classified by Immich) |
| Nextcloud | jpg, jpeg, png, gif, webp, bmp, heic, heif (or any image/ MIME type) |
| Synology NAS | jpg, jpeg, png, gif, webp, bmp, heic, heif |
Enable the Device Photos toggle in Settings. No additional setup is required — AndroSaver reads images from the device's external storage via MediaStore (up to 500 photos, sorted by most recent).
When no image source is enabled, AndroSaver automatically falls back to a set of bundled images stored in app/src/main/assets/default_images/ in this repository. Drop any JPEG, PNG, WebP, GIF, or BMP files into that folder and commit — they will be included in the next build and shown on any device where no source has been configured.
This lets you ship the app with a ready-to-use set of demo or placeholder photos out of the box. As soon as any source (Drive, Dropbox, Device Photos, etc.) is enabled, the bundled images are ignored.
- Get a free API key from openweathermap.org.
- Open AndroSaver Settings and enter the Weather City and API Key.
- Enable the Weather toggle.
Tap Preview in the Settings app to test the screensaver immediately without waiting for the system idle timeout.
- Android TV: Settings → Device Preferences → Screen saver → Select AndroSaver
- Tablet / Phone: Settings → Display → Screen saver → Select AndroSaver (exact path varies by Android version and OEM)
- The screensaver activates automatically when the device is idle (TV) or charging and idle (tablet/phone).
AndroSaver works on any Android device — not just Android TV. All features (photo slideshow, music visualizer, clock, weather) work as-is.
A few differences compared to TV:
- Remote navigation (← → to switch effects or skip photos, ↑ ↓ to adjust intensity) requires a connected keyboard or D-pad. Without one, the screensaver still runs; you just can't switch effects mid-session.
- Touch dismisses the screensaver in slideshow mode — this is standard Android behaviour.
- The screensaver activates while the device is charging and idle, rather than just idle.
All options are configured in the AndroSaver Settings app. The top-level Screensaver Mode picker switches between Photo Slideshow and Music Visualizer — only the relevant settings are shown.
Tap Image Sources on the main Settings screen to open the sources sub-page. A summary of currently-active sources is shown on the entry (e.g. "Google Drive, Dropbox"). Press Back to return to main Settings.
| Setting | Description |
|---|---|
| Google Drive toggle | Enable/disable fetching images from Google Drive |
| Google Drive Setup | Configure OAuth credentials and folder |
| OneDrive toggle | Enable/disable fetching images from Microsoft OneDrive |
| OneDrive Setup | Authorize with Microsoft account and set folder path |
| Dropbox toggle | Enable/disable fetching images from Dropbox |
| Dropbox Setup | Configure App Key/Secret and authorize |
| Immich toggle | Enable/disable fetching images from a self-hosted Immich server |
| Immich Setup | Configure host, API key, and optional album ID |
| Nextcloud toggle | Enable/disable fetching images from a Nextcloud instance |
| Nextcloud Setup | Configure host, credentials, and folder path |
| Synology NAS toggle | Enable/disable fetching images from a Synology NAS |
| Synology NAS Setup | Configure host, credentials, and folder path |
| Device Photos toggle | Enable/disable fetching images from local device storage |
All sources can be enabled at the same time — images from all sources are merged and shuffled. When no source is reachable, the last-fetched images are loaded from the local cache.
| Setting | Options | Default | Description |
|---|---|---|---|
| Time per Image | 5 s, 10 s, 15 s, 30 s, 1 min, 2 min, 5 min, 10 min, 15 min, 20 min, 30 min | 10 s | How long each image is displayed |
| Transition Speed | 1 s, 2 s, 3 s, 4 s, 5 s | 1.5 s | Duration of the animation between images |
| Transition Effect | Crossfade, Fade to Black, Slide Left, Slide Right, Zoom In, Zoom Out, Random | Crossfade | Animation style used between images |
| Ken Burns Effect | On / Off | On | Slow pan and zoom applied to each photo |
| Visualizer Overlay | On / Off | Off | Render the music visualizer semi-transparently over photos |
| Overlay Opacity | 0.1 – 1.0 | 0.3 | Opacity of the visualizer overlay |
| Effect | Description |
|---|---|
| Crossfade | Old image fades out while new image fades in simultaneously |
| Fade to Black | Old image fades to black, then new image fades in |
| Slide Left | New image slides in from the right, old slides out to the left |
| Slide Right | New image slides in from the left, old slides out to the right |
| Zoom In | New image scales up from slightly smaller while fading in |
| Zoom Out | Old image scales up and fades out as new image fades in |
| Random | A different effect is picked at random for each transition |
| Setting | Options | Default | Description |
|---|---|---|---|
| Visual Effect | Auto, Yantra, Cube, TriFlux, Lissajous, Tunnel, Corridor, Nova, Spiral, Bubbles, Plasma, Branches, Butterflies, FlowField, Vortex, Aurora, Lattice, Spectrum, Waterfall | Auto | Which visualizer to show; Auto cycles through all effects |
| Effect Intensity | Off, Low, Medium, High, Max | Low | How strongly the visuals react to the beat |
| Auto-cycle Interval | Off, 1 min, 2 min, 5 min, 10 min, 15 min | 2 min | How often the screensaver switches to the next effect |
| Music Genre | Any, Electronic, Rock, Classical | Any | Tunes beat-detection frequency weighting to the music style |
| Key | Action |
|---|---|
| ← | Previous effect |
| → | Next effect |
| ↑ | Increase intensity (one step) |
| ↓ | Decrease intensity (one step) |
| Any other key | Dismiss the screensaver |
Intensity changes made with the remote are saved and reflected in Settings. Switching effects (← / →) resets intensity to the last saved value.
The genre setting adjusts how the beat-detection algorithm weights bass frequency bins. It does not change the visual style directly — it changes what the algorithm considers a beat, making visuals more or less reactive to different frequency ranges.
Beat detection works on the lowest 20 FFT bins (roughly 0–860 Hz at 44100 Hz / 512-bin FFT). Each bin gets a weight multiplier; the weighted average of those 20 bins is compared against a short-term running average to detect transients. Genre changes only the per-bin weights:
| Genre | Bins boosted | Bins reduced | Net effect |
|---|---|---|---|
| Any | — (all ×1.0) | — | Flat — treats all bass frequencies equally |
| Electronic | 0–4 (~0–172 Hz) ×1.5 | 10–19 (~430–860 Hz) ×0.7 | Sub-bass boost + upper-bass cut — highly sensitive to 4-on-the-floor kick and synth bass; ignores mid-bass mud |
| Rock | 2–8 (~86–344 Hz) ×1.3 | — | Punchy mid-bass boost — better response to kick/snare hits and overdriven bass guitar; leaves sub-bass untouched |
| Classical | 10–19 (~430–860 Hz) ×1.4 | 0–9 (~0–387 Hz) ×0.6 | Strong sub-bass cut + upper-bass/low-mid boost — avoids false beats from bass-heavy mastering; responds to orchestral transients in the 400–800 Hz range |
If the visuals feel sluggish or fire on every bass rumble, try switching genre to match what is playing.
| Key | Action |
|---|---|
| → | Skip to next image |
| ← | Go back to previous image |
| Any other key | Dismiss the screensaver |
Manually skipping resets the auto-advance timer so the new image gets a full display duration.
These settings apply in both Slideshow and Visualizer mode.
| Setting | Options | Default | Description |
|---|---|---|---|
| Show Clock | On / Off | Off | Display time and date in the corner |
| Show Weather | On / Off | Off | Show current weather in the corner |
| Weather City | text | — | City name passed to OpenWeatherMap |
| OpenWeatherMap API Key | text | — | Free API key from openweathermap.org |
| Setting | Options | Default | Description |
|---|---|---|---|
| Schedule | On / Off | Off | Restrict the screensaver to an active time window |
| Active from / until | 0–23 h | 8 / 22 | Hour range during which the screensaver is allowed to run |
| Setting | Options | Default | Description |
|---|---|---|---|
| Update Channel | Stable, Dev | Stable (prod) / Dev (dev build) | Which GitHub Release to check for updates against |
| AndroSaver (version row) | — | — | Shows installed version; tapping installs a newer build when one is available (checked automatically each time Settings opens) |
See visualizer-music-reactivity.md for a detailed breakdown of how each effect reacts to bass, mid, high, and beat signals.
| Effect | Description |
|---|---|
| Yantra | Psychedelic sacred-geometry mandala with 7 concentric polygon rings, web connections, and neon spokes; rings spin at graduated speeds and kick outward on every beat |
| Cube | Dual wireframe cubes with slow rotation, motion trails, and spectrum colour-fade; two orbiting satellites leave additive-blend trails; size pulses on each beat |
| TriFlux ✨ | A living mosaic of triangles covering the full screen — every edge pulses with a rolling rainbow sweep; on beats, tiles eject to the foreground, bounce off screen edges, and spring back |
| Lissajous | 3D trefoil Lissajous knot with two-pass neon glow and hard beat spring burst |
| Tunnel | Smooth first-person ride through a curving neon tube; bass punches spawn dense bursts of triangles with rotating star polygons at each ring centre |
| Corridor ✨ | Infinite neon rainbow corridor — 28 luminous frames rush toward you; hue sweeps full spectrum far-to-near; bass drives speed; beats fire glowing spark particles that streak outward |
| Nova | Waveform kaleidoscope with 7-fold mirror symmetry across 4 spinning layers |
| Spiral | Neon helix vortex with 6 arms, audio-reactive radius breathing, cross-ring connections |
| Bubbles | Translucent full-screen rising bubbles driven by bass energy; synchronised beat pulse |
| Plasma | Full-screen sine-interference plasma with four overlapping wave fields |
| Branches ✨ | Psychedelic fractal lightning tree — nine neon arms split recursively to depth 7 with glowing halos and bright cores; mid frequencies twist branch angles live; beats fire extra arms |
| Spectrum | Log-spaced spectrum analyser with peak markers and waveform overlay |
| Waterfall | Scrolling time-frequency spectrogram; beat flashes the leading edge |
ScreensaverService (DreamService)
└── ScreensaverEngine
├── Photo Slideshow mode
│ ├── GoogleDriveSource ← Drive REST API v3 + OAuth token refresh
│ ├── OneDriveSource ← Microsoft Graph API + OAuth token refresh
│ ├── DropboxSource ← Dropbox API v2 + OAuth token refresh
│ ├── ImmichSource ← Immich REST API + API key auth
│ ├── NextcloudSource ← WebDAV PROPFIND + Basic Auth
│ ├── SynologySource ← Synology DSM FileStation API; re-login every 25 min
│ ├── LocalStorageSource ← MediaStore device photos + EXIF orientation
│ ├── ImageCache ← offline fallback (200 images / 300 MB); EXIF preserved
│ ├── ExifRotationTransformation ← corrects orientation for local/cached images
│ ├── Ken Burns animator ← pan/zoom per photo; always ends centered
│ └── VisualizerView ← optional overlay (semi-transparent)
├── Music Visualizer mode
│ ├── AudioEngine ← Android Visualizer API, FFT + beat detection
│ └── VisualizerView (GLSurfaceView)
│ └── VisualizerRenderer (OpenGL ES 2.0)
│ └── 13 × BaseMode ← Yantra, Cube, TriFlux, Lissajous, Tunnel,
│ Corridor, Nova, Spiral, Bubbles, Plasma,
│ Branches, Spectrum, Waterfall
├── Clock overlay ← date/time updated every minute
├── WeatherFetcher ← OpenWeatherMap, cached 30 min
└── Schedule check ← restricts active hours
SettingsActivity
├── SettingsFragment ← main screen
│ └── SourcesFragment ← Image Sources sub-screen (back-stack navigation)
├── GoogleDriveSetupActivity → GoogleAuthActivity (device flow)
├── OneDriveSetupActivity → OneDriveAuthActivity (device flow)
├── DropboxSetupActivity → DropboxAuthActivity (auth code flow)
├── ImmichSetupActivity
├── NextcloudSetupActivity
├── SynologySetupActivity
└── PreviewActivity ← in-app screensaver preview
UpdateChecker ← checks version.json on GitHub Releases (Stable/Dev)
UpdateInstaller ← downloads APK via OkHttp, installs via FileProvider
Images are loaded with Glide (OkHttp3 backend), scaled to display resolution, and rendered across two alternating ImageViews with configurable transition effects. EXIF orientation is applied for local and cached images via a custom BitmapTransformation; remote JPEG images are handled by Glide's built-in Downsampler. The visualizer is a Kotlin/OpenGL port of psysuals.
Credentials (OAuth tokens, API keys, passwords) are stored in Android SharedPreferences (on-device only). No data is sent to any third party except:
- The cloud service you configure (Google, Microsoft, Dropbox, your Immich/Nextcloud/Synology server)
- OpenWeatherMap (if the weather widget is enabled)
- GitHub Releases (to check for updates — only a version manifest is fetched; no identifying information is sent)
All Rights Reserved — see LICENSE.