Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,21 @@
</intent-filter>
</activity>

<!-- Media Browser Service for Android Auto -->
<!-- audio_service: media browser service used by Android Auto and
the media notification. Hosts a headless Flutter engine when the
car connects while the app UI is closed. -->
<service
android:name=".MusicService"
android:name="com.ryanheise.audioservice.AudioService"
android:exported="true"
android:enabled="true"
android:stopWithTask="false"
android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
<meta-data
android:name="android.media.browse.SEARCH_SUPPORTED"
android:value="true"/>
</service>
<!-- Media Button Receiver -->

<!-- audio_service media button receiver -->
<receiver
android:name="androidx.media.session.MediaButtonReceiver"
android:name="com.ryanheise.audioservice.MediaButtonReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON"/>
Expand Down
232 changes: 0 additions & 232 deletions android/app/src/main/kotlin/com/musly/musly/AndroidAutoPlugin.kt

This file was deleted.

35 changes: 2 additions & 33 deletions android/app/src/main/kotlin/com/musly/musly/AndroidSystemPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,28 +115,8 @@ object AndroidSystemPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
result.success(null)
}
"updatePlaybackState" -> {
val songId = call.argument<String>("songId")
val title = call.argument<String>("title") ?: ""
val artist = call.argument<String>("artist") ?: ""
val album = call.argument<String>("album") ?: ""
val artworkUrl = call.argument<String>("artworkUrl")
val duration = call.argument<Number>("duration")?.toLong() ?: 0L
val position = call.argument<Number>("position")?.toLong() ?: 0L
val playing = call.argument<Boolean>("playing") ?: false

// Ensure the service is running before updating state
val pushState = {
MusicService.getInstance()?.updatePlaybackState(
songId, title, artist, album, artworkUrl, duration, position, playing
)
}
if (MusicService.getInstance() == null) {
Log.d(TAG, "MusicService not running, requesting start via AndroidAutoPlugin")
AndroidAutoPlugin.startMusicService()
handler.postDelayed({ pushState() }, 200)
} else {
pushState()
}
// Media session metadata/state is now handled by audio_service
// (MuslyAudioHandler); nothing to do on this channel anymore.
result.success(null)
}
"setNotificationColor" -> {
Expand Down Expand Up @@ -167,17 +147,6 @@ object AndroidSystemPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
"getAndroidSdkVersion" -> {
result.success(Build.VERSION.SDK_INT)
}
"setRemotePlayback" -> {
val isRemote = call.argument<Boolean>("isRemote") ?: false
val volume = call.argument<Int>("volume") ?: 50
MusicService.getInstance()?.setRemoteVolume(isRemote, volume)
result.success(null)
}
"updateRemoteVolume" -> {
val volume = call.argument<Int>("volume") ?: 50
MusicService.getInstance()?.updateRemoteVolume(volume)
result.success(null)
}
"dispose" -> {
dispose()
result.success(null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,6 @@ class BluetoothMediaHelper(private val context: Context) {
currentPosition = position
isPlaying = playing

MusicService.getInstance()?.apply {
updatePlaybackState(songId, title, artist, album, artworkUrl, duration, position, playing)
}

artworkUrl?.let { url ->
loadArtworkAsync(url)
}
Expand Down
32 changes: 4 additions & 28 deletions android/app/src/main/kotlin/com/musly/musly/LyricsPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,48 +65,24 @@ class LyricsPlugin : MethodCallHandler, EventChannel.StreamHandler {
result.success(mapOf("initialized" to true))
}

private var pendingLyricsLine: String? = null

private fun updateLyrics(line: String?) {
if (line == null || line == currentLyricsLine) return

currentLyricsLine = line
pendingLyricsLine = line

// Update the media notification with the lyrics line as subtitle
val service = MusicService.getInstance()
if (service != null) {
service.updateLyrics(line)
pendingLyricsLine = null
Log.d(TAG, "Updated lyrics via MusicService: $line")
} else {
Log.d(TAG, "MusicService not ready, buffering lyrics: $line")
// Try again in 500ms
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
pendingLyricsLine?.let { pending ->
MusicService.getInstance()?.updateLyrics(pending)
if (MusicService.getInstance() != null) {
Log.d(TAG, "Delayed lyrics update succeeded: $pending")
pendingLyricsLine = null
}
}
}, 500)
}


// Notify Flutter listeners if any
eventSink?.success(mapOf(
"event" to "lyricsUpdated",
"currentLine" to line,
"timestamp" to System.currentTimeMillis()
))

Log.d(TAG, "Updated lyrics: $line")
}

private fun clearLyrics() {
currentLyricsLine = null
hasLyrics = false
MusicService.getInstance()?.clearLyrics()
Log.d(TAG, "Cleared lyrics")
}

Expand Down
10 changes: 5 additions & 5 deletions android/app/src/main/kotlin/com/musly/musly/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.devid.musly

import io.flutter.embedding.android.FlutterFragmentActivity
import com.ryanheise.audioservice.AudioServiceFragmentActivity
import io.flutter.embedding.engine.FlutterEngine

class MainActivity : FlutterFragmentActivity() {
// Extends AudioServiceFragmentActivity so the activity shares its Flutter
// engine with the audio_service MediaBrowserService (Android Auto).
class MainActivity : AudioServiceFragmentActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)

flutterEngine.plugins.add(AndroidAutoPlugin)


flutterEngine.plugins.add(AndroidSystemPlugin)

flutterEngine.plugins.add(BluetoothAvrcpPlugin)
Expand Down
Loading