DownloadManager is a singleton service that manages music downloads from Deezer. It ensures sequential download processing, tracks download state, and integrates with the local music library and MediaStore.
Source Location: app/src/main/java/com/crowstar/deeztrackermobile/features/download/DownloadManager.kt:27
Features
- Sequential Processing: Ensures only one download happens at a time
- Queue Management: Handles up to 20 queued download requests
- State Tracking: Real-time download state via Kotlin Flow
- MediaStore Integration: Automatically scans downloaded files into Android’s media library
- Playlist Integration: Can add downloaded tracks directly to playlists
- Duplicate Detection: Skips tracks that are already downloaded
- Coroutine Scope: Uses its own scope so downloads survive navigation
Initialization
getInstance()
Get or create the singleton instance.Application or activity context (will be converted to applicationContext internally)
The singleton DownloadManager instance
Properties
downloadState
Observable state flow of current download status
downloadRefreshTrigger
Counter that increments each time a track is successfully downloaded and confirmed in MediaStore. Use this to trigger UI refreshes.
currentQuality
Dynamic quality setting from user preferences. Reads from SharedPreferences key
audio_quality.FLAC, MP3_320, MP3_128
downloadDirectory
Base download directory path. Creates the directory if it doesn’t exist.
download_location:
"DOWNLOADS"→/storage/emulated/0/Download/Deeztracker"MUSIC"(default) →/storage/emulated/0/Music/Deeztracker
Methods
startTrackDownload()
Queue a single track for download.Deezer track ID
Track title (for display in download state)
Optional playlist ID. If provided, the track will be added to this playlist after download completes.
true if the download request was queued successfullystartAlbumDownload()
Queue an entire album for download.Deezer album ID
Album title (for display in download state)
true if the download request was queued successfullyThe manager will fetch the album’s track list from the Deezer API and download each track sequentially. Already-downloaded tracks are automatically skipped.
startPlaylistDownload()
Queue an entire playlist for download.Deezer playlist ID
Playlist title (for display in download state)
true if the download request was queued successfullyisDownloading()
Check if a download is currently in progress.true if a download is active, false otherwiseresetState()
Reset state toIdle if the download queue is empty. Call this after showing a completion notification to the user.
Example:
isTrackDownloaded()
Check if a track is already downloaded in the local library.Track title to search for
Artist name to search for
true if the track is found in local library (using normalized matching)This method uses smart normalization to match tracks:
- Title: Strips
feat./ft./featuring, removes special characters - Artist: Allows partial matching to handle multiple artists (e.g., “Artist A” matches “Artist A, Artist B”)
DownloadState
The download state is represented by a sealed class hierarchy:app/src/main/java/com/crowstar/deeztrackermobile/features/download/DownloadState.kt:15
Download Process Flow
- Queue Request: User calls
startTrackDownload(),startAlbumDownload(), orstartPlaylistDownload() - Sequential Processing: Requests are processed one at a time from the queue (max 20 queued)
- State Updates:
downloadStateemitsDownloadingstate - Duplicate Check: For albums/playlists, checks if tracks are already downloaded
- Download: Calls
RusteerServiceto download via Rust FFI - MediaStore Scan: Scans file into Android MediaStore
- Playlist Integration: If
targetPlaylistIdwas provided, adds track to playlist - Refresh Trigger: Increments
downloadRefreshTriggerto notify UI - Completion: Emits
CompletedorErrorstate
Integration Example
Complete example integrating DownloadManager in a Compose UI:Thread Safety
See Also
- RusteerService - Low-level Rust download service
- PlayerController - Playback control for downloaded tracks