feat: Add home screen music playback widget and some updates in Turkish localization (#98)

This commit is contained in:
eddyizm 2025-10-07 21:28:10 -07:00 committed by GitHub
commit f1d19142fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 1862 additions and 2 deletions

View file

@ -6,6 +6,8 @@ import android.app.TaskStackBuilder
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.os.Handler
import android.os.Looper
import androidx.media3.cast.CastPlayer
import androidx.media3.cast.SessionAvailabilityListener
import androidx.media3.common.AudioAttributes
@ -25,6 +27,7 @@ import com.cappielloantonio.tempo.util.DownloadUtil
import com.cappielloantonio.tempo.util.DynamicMediaSourceFactory
import com.cappielloantonio.tempo.util.Preferences
import com.cappielloantonio.tempo.util.ReplayGainUtil
import com.cappielloantonio.tempo.widget.WidgetUpdateManager
import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
@ -49,6 +52,18 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
companion object {
const val ACTION_BIND_EQUALIZER = "com.cappielloantonio.tempo.service.BIND_EQUALIZER"
}
private val widgetUpdateHandler = Handler(Looper.getMainLooper())
private var widgetUpdateScheduled = false
private val widgetUpdateRunnable = object : Runnable {
override fun run() {
if (!player.isPlaying) {
widgetUpdateScheduled = false
return
}
updateWidget()
widgetUpdateHandler.postDelayed(this, WIDGET_UPDATE_INTERVAL_MS)
}
}
override fun onCreate() {
super.onCreate()
@ -80,6 +95,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
override fun onDestroy() {
equalizerManager.release()
stopWidgetUpdates()
releasePlayer()
super.onDestroy()
}
@ -161,6 +177,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_SEEK || reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) {
MediaManager.setLastPlayedTimestamp(mediaItem)
}
updateWidget()
}
override fun onTracksChanged(tracks: Tracks) {
@ -183,6 +200,12 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
} else {
MediaManager.scrobble(player.currentMediaItem, false)
}
if (isPlaying) {
scheduleWidgetUpdates()
} else {
stopWidgetUpdates()
}
updateWidget()
}
override fun onPlaybackStateChanged(playbackState: Int) {
@ -195,6 +218,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
MediaManager.scrobble(player.currentMediaItem, true)
MediaManager.saveChronology(player.currentMediaItem)
}
updateWidget()
}
override fun onPositionDiscontinuity(
@ -230,6 +254,47 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
)
}
})
if (player.isPlaying) {
scheduleWidgetUpdates()
}
}
private fun updateWidget() {
val mi = player.currentMediaItem
val title = mi?.mediaMetadata?.title?.toString()
?: mi?.mediaMetadata?.extras?.getString("title")
val artist = mi?.mediaMetadata?.artist?.toString()
?: mi?.mediaMetadata?.extras?.getString("artist")
val album = mi?.mediaMetadata?.albumTitle?.toString()
?: mi?.mediaMetadata?.extras?.getString("album")
val coverId = mi?.mediaMetadata?.extras?.getString("coverArtId")
val position = player.currentPosition.takeIf { it != C.TIME_UNSET } ?: 0L
val duration = player.duration.takeIf { it != C.TIME_UNSET } ?: 0L
WidgetUpdateManager.updateFromState(
this,
title ?: "",
artist ?: "",
album ?: "",
coverId,
player.isPlaying,
player.shuffleModeEnabled,
player.repeatMode,
position,
duration
)
}
private fun scheduleWidgetUpdates() {
if (widgetUpdateScheduled) return
widgetUpdateHandler.postDelayed(widgetUpdateRunnable, WIDGET_UPDATE_INTERVAL_MS)
widgetUpdateScheduled = true
}
private fun stopWidgetUpdates() {
if (!widgetUpdateScheduled) return
widgetUpdateHandler.removeCallbacks(widgetUpdateRunnable)
widgetUpdateScheduled = false
}
private fun initializeLoadControl(): DefaultLoadControl {
@ -294,3 +359,5 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
player.prepare()
}
}
private const val WIDGET_UPDATE_INTERVAL_MS = 1000L