Android Music Player

BlackDice
Local Music Player

A native Android music player built with React Native & Expo. Scans your device audio library, plays tracks in the background, filters by folder, and delivers a full-screen now-playing experience — no streaming, no accounts, no internet. Just your music.

Android Native
Offline Only
Background Audio

Version

1.0.0

SDK

Expo SDK 54

Built

Mar 8, 2026

Platform

Android APK

Core Features

Device Library Scan

Scans all audio files on the device using expo-media-library, batched in pages of 200 for performance.

Background Playback

Audio continues playing when the screen is locked or the app is backgrounded, with full Android audio focus handling.

Folder Filtering

Include or exclude specific folders from the library. Preferences persist across sessions with AsyncStorage.

Player Features

Playback Controls

Full-screen now-playing screen with seek bar, track metadata, shuffle and repeat modes, and a persistent mini player visible across all screens.

Seek BarShuffleRepeat ModesMini Player

Library Management

Browse by songs, albums, and artists. Folder-level include/exclude controls. Queue management with next/previous track navigation.

Songs ViewAlbumsArtistsQueue

Technical Architecture

Key Decisions

All audio state — current track, queue, position, playback — lives in a single React Context backed by expo-av. No Redux, no external state library. The context owns the Sound object ref and polls status every second for position updates.

Single Context Architecture
LocalMusicContext owns all playback, library, and folder state
Background Audio Mode
expo-av Audio.setAudioModeAsync with staysActiveInBackground
File-based Routing
expo-router Stack + Tabs with MiniPlayer overlaid absolutely

Tech Stack

  • React Native 0.81 with Expo SDK 54
  • expo-av for audio playback and background mode
  • expo-media-library for device audio scanning
  • expo-router for file-based navigation
  • AsyncStorage for folder preference persistence
  • EAS Build for Android APK distribution

Technical Challenges

Background Audio on Android

Android aggressively kills background processes. Getting audio to survive app backgrounding required configuring expo-av with staysActiveInBackground, declaring FOREGROUND_SERVICE and FOREGROUND_SERVICE_MEDIA_PLAYBACK permissions in app.json, and setting UIBackgroundModes for iOS simultaneously.

Large Library Scan Performance

Scanning hundreds of audio files in one call blocked the UI. Solved by batching getAssetsAsync in pages of 200 with pagination cursors, updating a scanProgress value per batch so the UI stays responsive and shows real progress.

MiniPlayer Overlay Positioning

The persistent mini player needed to sit above the tab bar but below screen content on both iOS and Android. Solved with absolute positioning in the root tab layout, accounting for platform-specific safe area insets and tab bar height.

Audio State Across Navigation

expo-av Sound objects are not serializable and cannot be passed through navigation params. The solution was a single Context holding the Sound ref, so any screen can call playTrack, seek, or togglePlayPause without prop drilling or re-creating the audio instance.

Complete Tech Stack

  • React Native 0.81
  • TypeScript
  • Expo SDK 54
  • expo-av
  • expo-media-library
  • Background Audio
  • expo-router
  • React Navigation
  • AsyncStorage
  • expo-linear-gradient
v1.0.0 · Android APK

Get BlackDice

Download the APK directly. No Play Store, no account. Sideload it on any Android device and play your local music library immediately.

Android 8.0+ required · Enable "Install from unknown sources" in device settings