Turn an old Android photo frame into a dedicated Spotify now-playing display with a Raspberry Pi backend.
An old Android 4.2.2 digital photo frame is a pretty bad tablet, but it makes a great always-on now-playing screen.
This project keeps the frame as a thin Java client, moves Spotify auth and control to a local backend, and turns forgotten hardware into a clean wall-or-desk display.
Looping demo showing working pause and skip controls on the frame.
Android 4.2.2 minSdk 17 Java only Raspberry Pi backend Spotify Connect
- real hardware, not a mockup
- old Android 4.2.2 device reused instead of a new tablet
- Raspberry Pi backend with Spotify Connect support
- fullscreen kiosk-style UI with touch
pauseandskip - no AndroidX, no Kotlin, no WebView, no Spotify secrets on-device
If you like Raspberry Pi builds, Spotify hacks, weird Android salvage projects, or physical side projects with a clean UI, that is exactly what this repo is.
Spotify Frame is a thin Android client plus a small LAN backend.
The idea is simple:
- keep the old frame dumb and stable
- keep Spotify auth off the Android device
- render clean, readable now-playing UI from across the room
- let a Mac or Raspberry Pi handle the real logic
This project started on an old 1024x600 Wi-Fi photo frame with ADB access, a weird OEM launcher, and just enough hardware left to be useful.
- real hardware photo of the converted frame
- demo clip of touch
pauseandskipcontrols working on-device - clean fullscreen layout built for distance readability
You can reproduce this project if you have:
- an old Android device or photo frame with Wi-Fi
- ADB access
- a Mac, Linux box, or Raspberry Pi for the backend
- a Spotify account
- a local network shared by the backend and the frame
Best-fit devices:
- old Android tablets
- digital photo frames with Android underneath
- screens that are too weak for a modern Spotify client but still good at rendering one focused view
Most now-playing projects take the easy route:
- modern tablet
- web app
- full Spotify client on-device
This one does the opposite:
- Android 4.2.2
- no AndroidX
- no Kotlin
- no WebView
- one Java
Activity - local HTTP only
That constraint is the whole point. It turns a nearly useless device into a focused, always-on display.
- fetches now-playing data from a local backend every few seconds
- shows title, artist, album, state, progress, and cover art
- runs fullscreen in a kiosk-style layout
- keeps the screen awake
- works with
raspotify/librespoton a Raspberry Pi - supports touch controls when Spotify account permissions allow it
This is a Spotify now playing display built from:
- an old Android 4.2.2 photo frame
- a Java-only Android client
- a Flask + Spotipy backend
- Raspberry Pi /
raspotify/librespot - local HTTP API endpoints for metadata, control, and cover art
flowchart LR
A["Spotify app / Spotify Connect"] --> B["Raspotify / Librespot"]
B --> C["Event bridge"]
C --> D["Flask backend"]
D --> E["/api/now"]
D --> F["/api/control"]
D --> G["/cover.jpg"]
D --> H["/health"]
E --> I["Android frame client"]
F --> I
G --> I
Current target setup:
- old Android photo frame
- Android
4.2.2 - screen
1024x600 adbaccess- Raspberry Pi backend on the same LAN
The Android app is intentionally a render-only client. Spotify credentials, token refresh, cover caching, and playback state live on the backend.
app/ Android client
backend/ Flask backend, Spotipy integration, librespot event bridge
gradle/ Gradle wrapper files
docs/ README assets
python3 -m venv work/.venv-backend
source work/.venv-backend/bin/activate
pip install -r backend/requirements.txt
cp backend/.env.example backend/.env
python backend/authorize.py
python backend/run.pyFor Raspberry Pi + raspotify, see backend/README.md.
./gradlew -PspotifyFrameBackendUrl=http://192.168.1.50:8000 assembleDebugadb install -r app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n com.janek.spotifyframe/.MainActivityIf you want the most interesting setup, use a Raspberry Pi running raspotify as the dedicated playback backend and keep the frame as a simple LAN display client.
- Android SDK 17
- Java
- Flask
- Spotipy
raspotify/librespotHttpURLConnectionorg.json.JSONObject
Already working:
- Android 4.2.2-compatible display client
- local backend with Spotify auth
- album art caching
- fullscreen now-playing UI
- progress rendering
- touch playback controls
- Raspberry Pi deployment
Still worth improving:
- stronger resilience when router IPs change
- cleaner first-time setup flow
- smarter fallback behavior for missing playback state
- optional voice control / wake-word mode
- better real-world photos of the hardware
- cleaner “clone this exact setup” guide for other people
The app deliberately stays minimal:
- no Spotify secrets on Android
- no
/systemmodification required for the normal APK flow - no heavy UI framework
- no modern compatibility stack unless truly needed
That keeps the frame lightweight and makes the system easier to reason about when something on the network changes.
- This repo does not include live Spotify tokens, local
.envfiles, APK outputs, or extracted OEM system backups. - Cover art and playback data are served over LAN, so the backend host matters.
- If playback is controlled from a different Spotify account than the one authorized for control, display can still work while touch controls may be limited.
API contract, Raspberry Pi setup, and backend-specific notes live in backend/README.md.
- star the repo
- fork it for your own old-screen build
- open an issue if you want to adapt it to another Android frame or tablet


