Skip to content

Commit

Permalink
Add support Android Auto Success
Browse files Browse the repository at this point in the history
  • Loading branch information
maxrave-dev committed Nov 5, 2023
1 parent c85eccc commit 13f7ab6
Show file tree
Hide file tree
Showing 19 changed files with 751 additions and 175 deletions.
33 changes: 29 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
android:usesCleartextTraffic="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:appCategory="audio"
android:supportsRtl="true"
android:localeConfig="@xml/locale_config"
android:networkSecurityConfig="@xml/network_security_config"
Expand Down Expand Up @@ -124,16 +125,24 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>

<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
<meta-data
android:name="androidx.car.app.TintableAttributionIcon"
android:resource="@drawable/logo_simpmusic_01_removebg_preview" />

<service
android:name=".service.SimpleMediaService"
android:foregroundServiceType="mediaPlayback"
android:stopWithTask="false"
android:exported="false">
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
<action android:name="androidx.media3.session.MediaSessionService" />
<action android:name="androidx.media3.session.MediaLibraryService" />
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
<service android:name=".service.test.download.MusicDownloadService"
Expand All @@ -152,10 +161,26 @@
android:name="autoStoreLocales"
android:value="true" />
</service>
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>

<meta-data
android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc" />
</application>

<uses-feature
android:name="android.hardware.type.automotive"
android:required="true" />

<uses-feature
android:name="android.hardware.wifi"
android:required="false" />
<uses-feature
android:name="android.hardware.screen.portrait"
android:required="false" />
<uses-feature
android:name="android.hardware.screen.landscape"
android:required="false" />

<queries>
<intent>
<action android:name="android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
import androidx.media3.datasource.cache.NoOpCacheEvictor
import androidx.media3.datasource.cache.SimpleCache
import com.maxrave.simpmusic.data.dataStore.DataStoreManager
import com.maxrave.simpmusic.data.repository.MainRepository
import com.maxrave.simpmusic.service.SimpleMediaSessionCallback
import dagger.Module
import dagger.Provides
Expand Down Expand Up @@ -65,5 +66,8 @@ object MusicServiceModule {

@Provides
@Singleton
fun provideMediaSessionCallback() : SimpleMediaSessionCallback = SimpleMediaSessionCallback()
fun provideMediaSessionCallback(
@ApplicationContext context: Context,
mainRepository: MainRepository
): SimpleMediaSessionCallback = SimpleMediaSessionCallback(context, mainRepository)
}
69 changes: 68 additions & 1 deletion app/src/main/java/com/maxrave/simpmusic/extension/AllExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.text.Html
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
import androidx.core.net.toUri
import androidx.datastore.preferences.preferencesDataStore
import androidx.lifecycle.LiveData
Expand Down Expand Up @@ -299,8 +300,28 @@ fun MediaItem?.toSongEntity(): SongEntity? {
downloadState = 0
) else null
}

@JvmName("MediaItemtoSongEntity")
@UnstableApi
fun SongEntity.toMediaItem(): MediaItem {
return MediaItem.Builder()
.setMediaId(this.videoId)
.setUri(this.videoId)
.setCustomCacheKey(this.videoId)
.setMediaMetadata(
MediaMetadata.Builder()
.setTitle(this.title)
.setArtist(this.artistName?.connectArtists())
.setArtworkUri(this.thumbnails?.toUri())
.setAlbumTitle(this.albumName)
.build()
)
.build()
}

@JvmName("TracktoMediaItem")
@UnstableApi
fun Track.toMediaItem() : MediaItem {
fun Track.toMediaItem(): MediaItem {
return MediaItem.Builder()
.setMediaId(this.videoId)
.setUri(this.videoId)
Expand Down Expand Up @@ -649,6 +670,52 @@ fun List<PodcastBrowse.EpisodeItem>.toListTrack(): ArrayList<Track> {
return listTrack
}

fun TextView.setTextAnimation(
text: String,
duration: Long = 300,
completion: (() -> Unit)? = null
) {
if (text != "null") {
fadOutAnimation(duration) {
this.text = text
fadInAnimation(duration) {
completion?.let {
it()
}
}
}
}
}

fun View.fadOutAnimation(
duration: Long = 300,
visibility: Int = View.INVISIBLE,
completion: (() -> Unit)? = null
) {
animate()
.alpha(0f)
.setDuration(duration)
.withEndAction {
this.visibility = visibility
completion?.let {
it()
}
}
}

fun View.fadInAnimation(duration: Long = 300, completion: (() -> Unit)? = null) {
alpha = 0f
visibility = View.VISIBLE
animate()
.alpha(1f)
.setDuration(duration)
.withEndAction {
completion?.let {
it()
}
}
}

operator fun File.div(child: String): File = File(this, child)
fun String.toSQLiteQuery(): SimpleSQLiteQuery = SimpleSQLiteQuery(this)
fun InputStream.zipInputStream(): ZipInputStream = ZipInputStream(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import android.os.Binder
import android.os.IBinder
import android.util.Log
import androidx.core.net.toUri
import androidx.media3.cast.CastPlayer
import androidx.media3.cast.DefaultMediaItemConverter
import androidx.media3.cast.SessionAvailabilityListener
import androidx.media3.common.AudioAttributes
import androidx.media3.common.C
import androidx.media3.common.Player
Expand All @@ -34,11 +31,9 @@ import androidx.media3.extractor.mkv.MatroskaExtractor
import androidx.media3.extractor.mp4.FragmentedMp4Extractor
import androidx.media3.session.DefaultMediaNotificationProvider
import androidx.media3.session.MediaController
import androidx.media3.session.MediaLibraryService
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import androidx.media3.session.SessionToken
import coil.ImageLoader
import com.google.android.gms.cast.framework.CastContext
import com.google.common.util.concurrent.MoreExecutors
import com.maxrave.simpmusic.R
import com.maxrave.simpmusic.common.MEDIA_NOTIFICATION
Expand All @@ -54,16 +49,15 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.cancellable
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import java.util.concurrent.Executors
import javax.inject.Inject

@AndroidEntryPoint
@UnstableApi
class SimpleMediaService : MediaSessionService() {
class SimpleMediaService : MediaLibraryService() {

lateinit var player: ExoPlayer

lateinit var mediaSession: MediaSession
lateinit var mediaSession: MediaLibrarySession

@Inject
lateinit var dataStoreManager: DataStoreManager
Expand Down Expand Up @@ -104,10 +98,11 @@ class SimpleMediaService : MediaSessionService() {
.setRenderersFactory(provideRendererFactory(this))
.build()

mediaSession = provideMediaSession(
context = this,
player = player,
callback = simpleMediaSessionCallback,
mediaSession = provideMediaLibrarySession(
this,
this,
player,
simpleMediaSessionCallback
)
val sessionToken = SessionToken(this, ComponentName(this, SimpleMediaService::class.java))
val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync()
Expand All @@ -119,7 +114,7 @@ class SimpleMediaService : MediaSessionService() {
return super.onStartCommand(intent, flags, startId)
}

override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession =
override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaLibrarySession =
mediaSession

@UnstableApi
Expand Down Expand Up @@ -284,9 +279,28 @@ class SimpleMediaService : MediaSessionService() {
@UnstableApi
fun provideCoilBitmapLoader(context: Context): CoilBitmapLoader = CoilBitmapLoader(context)


@UnstableApi
fun provideMediaLibrarySession(
context: Context,
service: MediaLibraryService,
player: ExoPlayer,
callback: SimpleMediaSessionCallback
): MediaLibrarySession = MediaLibrarySession.Builder(
service, player, callback
)
.setSessionActivity(
PendingIntent.getActivity(
context, 0, Intent(context, MainActivity::class.java),
PendingIntent.FLAG_IMMUTABLE
)
)
.setBitmapLoader(provideCoilBitmapLoader(context))
.build()

@UnstableApi
fun provideMediaSession(
context: Context,
context: Context,
player: ExoPlayer,
callback: SimpleMediaSessionCallback
): MediaSession =
Expand Down
Loading

0 comments on commit 13f7ab6

Please sign in to comment.