Swift Radio, now on Android
People kept asking for it. Every few months, someone would open an issue or send an email: "Is there an Android version?" For ten years, the answer was no. Swift Radio was iOS-only. Now it runs on both.
Swift Radio Android is not a wrapper or a cross-platform port. It is a native Android app, built from scratch with Kotlin and Jetpack Compose. If you already run the iOS version, the same stations.json file works on both platforms without changes. Drop it in and your stations show up.


Same format, different platform
The iOS and Android versions share the same station JSON schema. If you have a remote stations.json powering Swift Radio on iOS, point the Android app at the same URL and it works. No conversion, no mapping. This was a deliberate choice to make maintaining both platforms as simple as changing one file.
{
"station": [
{
"name": "Station Name",
"streamURL": "https://example.com/stream",
"imageURL": "station-image",
"desc": "Short description",
"longDesc": "Detailed description for the info sheet.",
"website": "https://example.com"
}
]
}
Station images can be bundled assets or remote URLs, same as iOS.
What it does
The feature set matches the iOS version where it matters, and uses Android-native equivalents where the platforms diverge:
- Android Auto: full browse tree with station artwork, playback controls, and metadata. Think of it as CarPlay, but for the other side of the aisle.
- Background playback: audio continues when the app is backgrounded, with lock screen and notification controls via a Media3 session.
- Live metadata: ICY stream metadata updates the track name and artist in real time. Album art pulls from the iTunes Search API when available.
- Search and filter: a search bar filters stations by name or description. Toggled on or off in
Config.kt. - Material You: on Android 12+, the app picks up the device's dynamic color palette. On older devices, it falls back to a default dark theme.
- Pull-to-refresh: swipe down on the station list to reload from the JSON source.
- Localization-ready: all user-facing strings live in
strings.xml. Add avalues-XXfolder for a new language and Android handles the rest.
Under the hood
The entire UI is Jetpack Compose with Material 3. No XML layouts, no fragments. Navigation between the station list and the now playing screen uses Compose navigation with a shared PlayerViewModel that bridges the UI to the audio service.
Audio playback runs on Media3 ExoPlayer inside a foreground service. The MediaLibraryService exposes a browse tree for Android Auto and any other MediaBrowser client. Artwork for bundled station images is embedded directly into the media metadata as a byte array, because Android Auto cannot resolve file:///android_asset/ URIs the way a local app can.
Networking uses Ktor with Kotlinx Serialization for JSON parsing, and Coil handles image loading and caching throughout the app.
| Library | Purpose |
|---|---|
| AndroidX Media3 | Audio playback, media session, Android Auto |
| Jetpack Compose | UI framework with Material 3 |
| Coil | Image loading and caching |
| Ktor | HTTP client for remote station loading |
| Kotlinx Serialization | JSON parsing |
Getting started
The setup is the same idea as the iOS version. Fork, configure, build:
- Open the project in Android Studio
- Edit
Config.ktto set your stations URL, contact info, and feature flags - Replace the stations in
app/src/main/assets/stations.jsonwith your own - Build and run
The app targets Android 7.0+ (API 24), which covers the vast majority of active devices.
About the name
Yes, it is called Swift Radio and it is written in Kotlin. The name comes from the iOS original, which has been around since 2015 and has nearly 3,000 stars on GitHub. The Android version keeps the name because the project, the station format, and the community are the same. The language is just a detail.
What's next
The v3 iOS release laid the groundwork for a shared architecture across platforms. The Android version is now at feature parity for the core experience. Next up: a single-station version for both iOS and Android, bundled together.
Star the repo if it is useful, fork it if you want to make it yours.