android auto more stuff

This commit is contained in:
Boof2015
2026-06-29 17:29:45 -04:00
parent de7ad39d62
commit 19a2e30d0b
10 changed files with 89 additions and 1 deletions
@@ -116,6 +116,10 @@ class AstraCarCommandService : HeadlessJsTaskService() {
)
}
fun startFavoriteAction(context: Context) {
start(context, Intent(context, AstraCarCommandService::class.java).putExtra(EXTRA_COMMAND, AstraCarFavoriteAction.COMMAND))
}
fun startPlayFromMediaId(context: Context, mediaId: String?) {
val media = AstraCarMediaIds.decode(mediaId) ?: return
start(
@@ -0,0 +1,6 @@
package expo.modules.astracar
object AstraCarFavoriteAction {
const val TOGGLE = "astra.favorite.toggle"
const val COMMAND = "toggleFavorite"
}
@@ -51,6 +51,14 @@ class AstraCarMediaService : MediaBrowserServiceCompat() {
override fun onPlayFromSearch(query: String?, extras: Bundle?) {
AstraCarCommandService.startPlayFromSearch(this@AstraCarMediaService, query, extras)
}
override fun onCustomAction(action: String?, extras: Bundle?) {
if (action == AstraCarFavoriteAction.TOGGLE) {
AstraCarCommandService.startFavoriteAction(this@AstraCarMediaService)
} else {
super.onCustomAction(action, extras)
}
}
},
)
applyAstraState(AstraCarNowPlayingStore.load(this@AstraCarMediaService))
@@ -37,6 +37,12 @@ class AstraCarNowPlayingRecord : Record {
@Field
val position: Double? = null
@Field
val trackPath: String? = null
@Field
val isFavorite: Boolean = false
}
class AstraCarModule : Module() {
@@ -56,6 +62,8 @@ class AstraCarModule : Module() {
hasTrack = state.hasTrack,
durationSeconds = state.duration,
positionSeconds = state.position,
trackPath = state.trackPath,
isFavorite = state.isFavorite,
),
)
}
@@ -16,6 +16,8 @@ data class AstraCarNowPlayingState(
val hasTrack: Boolean,
val durationSeconds: Double?,
val positionSeconds: Double?,
val trackPath: String?,
val isFavorite: Boolean,
)
object AstraCarNowPlayingStore {
@@ -94,9 +96,19 @@ object AstraCarNowPlayingStore {
((state.positionSeconds ?: 0.0) * 1000).toLong(),
if (playbackState == PlaybackStateCompat.STATE_PLAYING) 1f else 0f,
)
.apply {
favoriteAction(state)?.let(::addCustomAction)
}
.build()
}
private fun favoriteAction(state: AstraCarNowPlayingState): PlaybackStateCompat.CustomAction? {
if (!state.hasTrack || state.trackPath.isNullOrBlank()) return null
val label = if (state.isFavorite) "Unfavorite" else "Favorite"
val icon = if (state.isFavorite) R.drawable.ic_astra_favorite else R.drawable.ic_astra_favorite_border
return PlaybackStateCompat.CustomAction.Builder(AstraCarFavoriteAction.TOGGLE, label, icon).build()
}
private fun encode(state: AstraCarNowPlayingState): String =
JSONObject()
.put("title", state.title)
@@ -107,6 +119,8 @@ object AstraCarNowPlayingStore {
.put("hasTrack", state.hasTrack)
.put("durationSeconds", state.durationSeconds)
.put("positionSeconds", state.positionSeconds)
.put("trackPath", state.trackPath)
.put("isFavorite", state.isFavorite)
.toString()
private fun decode(value: String?): AstraCarNowPlayingState {
@@ -122,6 +136,8 @@ object AstraCarNowPlayingStore {
hasTrack = json.optBoolean("hasTrack", false),
durationSeconds = json.optDoubleOrNull("durationSeconds"),
positionSeconds = json.optDoubleOrNull("positionSeconds"),
trackPath = json.optNullableString("trackPath"),
isFavorite = json.optBoolean("isFavorite", false),
)
}.getOrDefault(emptyState())
}
@@ -136,6 +152,8 @@ object AstraCarNowPlayingStore {
hasTrack = false,
durationSeconds = null,
positionSeconds = null,
trackPath = null,
isFavorite = false,
)
private fun JSONObject.optNullableString(key: String): String? {
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z" />
</vector>
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M16.5,3c-1.74,0 -3.41,0.81 -4.5,2.09C10.91,3.81 9.24,3 7.5,3 4.42,3 2,5.42 2,8.5c0,3.78 3.4,6.86 8.55,11.54L12,21.35l1.45,-1.32C18.6,15.36 22,12.28 22,8.5 22,5.42 19.58,3 16.5,3zM12.1,18.55l-0.1,0.1 -0.1,-0.1C7.14,14.24 4,11.39 4,8.5 4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5 0,2.89 -3.14,5.74 -7.9,10.05z" />
</vector>