Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/CesarArellano/Music-Player-App/llms.txt

Use this file to discover all available pages before exploring further.

With dependencies installed and a device connected, you are ready to launch Musynth. This page covers every run and build command you will need, explains the first-launch permission prompts and artwork-cache initialization sequence, and shows you how to confirm background playback is functioning correctly on both Android and iOS.
1

Connect a device or start an emulator

Check which devices Flutter can see:
flutter devices
You should see at least one Android or iOS entry. If the list is empty, verify that USB debugging is enabled on your Android device (or that the iOS Simulator is running) and that flutter doctor reports a healthy toolchain.
2

Run in debug mode

Debug mode includes hot-reload, the Flutter DevTools overlay, and verbose logging — ideal for development.
flutter run
# Flutter selects the connected Android device automatically.
# To target a specific device: flutter run -d <device-id>
Use flutter run --verbose to see the full output of the Gradle / Xcode build. This is helpful when debugging native build errors related to the music_query_selector plugin.
3

Grant permissions on first launch

Musynth requests several permissions during startup. On the very first launch you will see one or more system dialogs:
  1. Notification permission (Android 13+) — requested programmatically in main() via Permission.notification.request() before AudioService is initialized. This must be granted for the media playback notification to appear. Without it, the notification channel is created but the notification remains hidden.
  2. Media / storage access — requested when the library scan begins:
    • Android 13+: READ_MEDIA_AUDIO (and READ_MEDIA_IMAGES for artwork)
    • Android 12 and below: READ_EXTERNAL_STORAGE
  3. Microphone (optional) — requested only when you tap the mic icon in the search screen for voice search.
If you deny the media read permission, Musynth’s library will be empty and the Songs/Albums/Artists/Genres tabs will show no content. Go to Settings → Apps → Musynth → Permissions to grant it manually after the fact.
4

Wait for the artwork cache to initialize

On the first launch after installation (or after clearing app data), Musynth scans every audio file on the device and builds a local album-artwork cache. During this process:
  • The LibraryCubit sets isCreatingArtworks: true in its state.
  • The home screen observes this flag and displays a loading/splash indicator instead of the library tabs.
  • Once all artwork files have been written to the app’s private cache directory, isCreatingArtworks flips to false and the full tab UI appears.
On a library of a few hundred tracks this takes only a few seconds. On very large libraries (thousands of songs) it may take longer on the first run; subsequent launches are instant because the cache already exists.
5

Run in release mode

Release mode disables the Flutter debug overlay and applies full AOT compilation. Use it to test performance and measure real-world behavior.
flutter run --release
The build.gradle.kts release build type currently uses the debug signing config as a placeholder. For a distributable release build, configure a proper keystore first (see the Installation page).
6

Build distribution artifacts

When you are ready to distribute, use the build commands below instead of flutter run:
flutter build apk --release
# Output: build/app/outputs/flutter-apk/app-release.apk
7

Verify background playback

Background playback is one of Musynth’s core features — here is how to confirm it is working:
  1. Start playing any track.
  2. Lock your screen (or press the Home button to background the app).
  3. On Android: pull down the notification shade — you should see the Musynth persistent media notification with album art, track title, and transport controls (previous, play/pause, next). The notification is configured as androidNotificationOngoing: true, so it cannot be dismissed while music is playing.
  4. On iOS: swipe up to the Control Center or view the lock screen — the Now Playing widget should show the current track with controls.
  5. Use the hardware media buttons (headphones, Bluetooth device) or the notification controls to skip tracks and pause/resume — these are routed through the AudioPlayerHandler foreground service.
If the media notification does not appear on Android 13+, the most likely cause is that the POST_NOTIFICATIONS permission was denied at the first-launch prompt. Musynth requests it via Permission.notification.request() in main() before AudioService.init() — granting it at that prompt is essential.
8

Explore Android-only features

Two features are guarded with Platform.isAndroid checks and will only appear when running on Android:
The home screen TabController is initialized with length: Platform.isAndroid ? 6 : 5. On Android a Playlists tab is inserted as the fourth tab (after Songs, Albums, and Artists), letting you create, rename, and manage device playlists. On iOS the tab is not rendered and the controller length is 5.
The Delete option in the song context menu uses MediaStore.createDeleteRequest on Android 11+ (a system confirmation dialog), a RecoverableSecurityException flow on Android 10, and a direct delete on Android 9 and below. On iOS the option is hidden because deleteSongs is not implemented in the iOS plugin and the code is wrapped in a Platform.isAndroid guard. After a confirmed delete, the song is removed from the live queue and playback advances to the next track automatically.

Common Run-Time Issues

The media read permission was likely denied. On Android, go to Settings → Apps → Musynth → Permissions → Files and media and set it to Allow. Then force-stop and relaunch the app to trigger a fresh library scan.
Open Settings → Apps → Musynth → Notifications and enable the Musynth notification channel. Alternatively, clear app data and relaunch so the POST_NOTIFICATIONS prompt is shown again.
This usually means the music_query_selector companion repo is missing or was cloned in the wrong location. Re-read the Installation page and confirm the directory structure matches the required sibling layout.
Ensure CocoaPods is installed (pod --version) and that you ran pod install from the ios/ directory after flutter pub get. If it still fails, try pod repo update then pod install --repo-update.

Build docs developers (and LLMs) love