Membangun dan menguji aplikasi parkir untuk Android Automotive OS: Mendukung audio saat mengemudi

1. Sebelum memulai

Tidak termasuk dalam cakupan

  • Panduan tentang cara membuat aplikasi media (audio - misalnya musik, radio, podcast) untuk Android Auto dan Android Automotive OS. Lihat Membangun aplikasi media untuk mobil guna mengetahui detail tentang cara membangun aplikasi serupa.

Yang akan Anda butuhkan

Yang akan Anda bangun

Dalam codelab ini, Anda akan mempelajari cara menambahkan dukungan untuk audio saat mengemudi di Road Reels, aplikasi yang sudah ada, serta mendukung perangkat seluler dan Android Automotive OS.

Versi awal aplikasi akan menjeda pemutaran saat batasan pengalaman pengguna aktif.

Versi aplikasi yang telah selesai akan melanjutkan pemutaran saat batasan pengalaman pengguna aktif.

Yang akan Anda pelajari

  • Cara mengaktifkan pemutaran audio latar belakang di aplikasi video di Android Automotive OS

2. Memulai persiapan

Mendapatkan kode

  1. Kode untuk codelab ini dapat ditemukan di direktori build-a-parked-app dalam repositori GitHub car-codelabs. Untuk membuat clone kode ini, jalankan perintah berikut:
git clone https://github.com/android/car-codelabs.git
  1. Atau, Anda dapat mendownload repositori sebagai file ZIP:

Membuka project

  • Setelah memulai Android Studio, impor project dengan memilih direktori build-a-parked-app/end saja. Direktori build-a-parked-app/audio-while-driving berisi kode solusi yang dapat Anda rujuk kapan saja jika Anda mengalami kebuntuan atau hanya ingin melihat project lengkap.

Memahami kode

  • Setelah membuka project di Android Studio, luangkan waktu untuk memeriksa kode awal.

3. Mempelajari aplikasi parkir untuk Android Automotive OS

Aplikasi parkir merupakan subkumpulan kategori aplikasi yang didukung oleh Android Automotive OS. Pada saat penulisan codelab ini, aplikasi tersebut terdiri dari aplikasi streaming video, browser web, dan game. Aplikasi ini sangat cocok untuk mobil, mengingat hardware yang ada di kendaraan yang dilengkapi Google dan meningkatnya prevalensi kendaraan listrik. Waktu pengisian daya memberikan peluang besar bagi pengemudi dan penumpang untuk berinteraksi dengan jenis aplikasi ini.

Dalam banyak hal, mobil mirip dengan perangkat layar besar lainnya seperti tablet dan perangkat foldable. Mobil memiliki layar sentuh dengan ukuran, resolusi, dan rasio aspek yang serupa, dan bisa saja dalam orientasi potret atau lanskap (meskipun, tidak seperti tablet, orientasi layar mobil tetap). Mobil juga merupakan perangkat terhubung yang dapat masuk dan keluar dari koneksi jaringan. Dengan semua hal itu, tidak mengherankan jika aplikasi yang sudah dioptimalkan untuk perangkat layar besar sering kali memerlukan sedikit saja upaya untuk menghadirkan pengalaman pengguna yang sangat baik di mobil.

Serupa dengan perangkat layar besar, ada juga tingkat kualitas aplikasi untuk aplikasi di mobil:

  • Tingkat 3 - Siap digunakan di mobil: Aplikasi Anda kompatibel dengan perangkat layar besar dan dapat digunakan saat mobil diparkir. Meskipun aplikasi ini mungkin tidak memiliki fitur yang dioptimalkan untuk mobil, pengguna dapat menikmati aplikasi ini seperti yang mereka lakukan di perangkat Android layar besar lainnya. Aplikasi seluler yang memenuhi persyaratan ini layak didistribusikan ke mobil secara apa adanya melalui program aplikasi seluler siap digunakan untuk mobil.
  • Tingkat 2 - Dioptimalkan untuk mobil: Aplikasi Anda memberikan pengalaman yang sangat baik pada tampilan stack tengah mobil. Agar dapat digunakan di mobil, aplikasi Anda harus melalui beberapa rekayasa khusus mobil untuk menyertakan kemampuan yang dapat digunakan di seluruh mode mengemudi atau parkir, bergantung pada kategori aplikasi Anda.
  • Tingkat 1 - Dirancang khusus untuk mobil: Aplikasi Anda dibuat agar berfungsi di berbagai hardware pada mobil dan dapat menyesuaikan pengalamannya di seluruh mode mengemudi dan parkir. Aplikasi ini pada tingkat ini memberikan pengalaman pengguna terbaik yang didesain untuk berbagai layar di mobil, seperti konsol tengah, cluster instrumen, dan layar tambahan, seperti tampilan panorama yang terlihat di banyak mobil premium.

Dalam codelab ini, Anda akan menerapkan audio saat mengemudi, yang merupakan fitur Tingkat 1, sehingga aplikasi ini menjadi aplikasi yang Dirancang khusus untuk mobil.

4. Menjalankan aplikasi di emulator Android Automotive OS

Menginstal Image Sistem Automotive with Play Store

  1. Pertama, buka SDK Manager di Android Studio, lalu pilih tab SDK Platforms jika belum dipilih. Di pojok kanan bawah jendela SDK Manager, pastikan kotak Show package details dicentang.
  2. Instal salah satu image emulator Android Automotive API 34 yang tercantum di Add generic system images. Image hanya dapat berjalan di komputer dengan arsitektur yang sama (x86/ARM) dengan image itu sendiri.

Membuat Perangkat Virtual Android untuk Android Automotive OS

  1. Setelah membuka Pengelola Perangkat, pilih Automotive di kolom Category di sisi kiri jendela. Kemudian, pilih profil hardware gabungan Automotive (1408p landscape) dari daftar, lalu klik Next.

6a32a01404a7729f.png

  1. Di halaman berikutnya, pilih image sistem dari langkah sebelumnya. Klik Next dan pilih opsi lanjutan yang Anda inginkan sebelum akhirnya membuat AVD dengan mengklik Finish.

Menjalankan aplikasi

Jalankan aplikasi di emulator yang baru saja Anda buat menggunakan konfigurasi run app. Uji perilaku aplikasi dengan membuka layar pemutar dan menyimulasikan aktivitas mengemudi.

5. Mendeteksi dukungan untuk audio saat mengemudi

Karena audio saat mengemudi hanya didukung di kendaraan tertentu, Anda harus mendeteksi apakah perangkat saat ini mendukung fitur tersebut dan menyesuaikan perilaku aplikasi Anda. Untuk melakukannya, Anda dapat menggunakan class CarFeatures dari library androidx.car.app:app.

  1. Tambahkan dependensi pada artefak androidx.car.app:app.

libs.version.toml

[versions]
...
carApp = "1.7.0-rc01"


[libraries]
...
androidx-car-app = { group = "androidx.car.app", name = "app", version.ref = "carApp" }

build.gradle.kts (Module :app)

implementation(libs.androidx.car.app)
  1. Di RoadReelsPlayer, Anda kemudian dapat menentukan apakah fitur tersebut didukung dan memperbarui logika yang digunakan untuk menghitung nilai shouldPreventPlay.

RoadReelsPlayer.kt

if (packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
    ...

    val isBackgroundAudioWhileDrivingSupported = CarFeatures.isFeatureEnabled(
        context,
        CarFeatures.FEATURE_BACKGROUND_AUDIO_WHILE_DRIVING
    )

    shouldPreventPlay = !isBackgroundAudioWhileDrivingSupported &&
            carUxRestrictionsManager.currentCarUxRestrictions.isRequiresDistractionOptimization
    invalidateState()

    carUxRestrictionsManager.registerListener { carUxRestrictions: CarUxRestrictions ->
        shouldPreventPlay = !isBackgroundAudioWhileDrivingSupported &&
            carUxRestrictions.isRequiresDistractionOptimization
        ...
    }
}

Jalankan kembali aplikasi dengan perubahan ini dan simulasikan aktivitas mengemudi. Perhatikan bahwa pemutaran audio kini dilanjutkan saat UI aplikasi terhalang oleh sistem. Namun, Anda belum selesai. Untuk memenuhi semua persyaratan, Anda harus melakukan beberapa perubahan lagi.

6. Mendukung pemutaran di latar belakang

Saat ini, pemutaran media aplikasi ditangani oleh aktivitas. Dengan demikian, pemutaran media dapat dilanjutkan selama jangka waktu singkat setelah batasan pengalaman pengguna menjadi aktif dan aktivitas disamarkan, tetapi aplikasi Anda pada akhirnya akan di-cache oleh sistem, sehingga pemutaran berakhir.

Untuk mendukung pemutaran yang berjalan lama, aplikasi harus diupdate untuk menggunakan layanan guna menangani pemutaran. Hal ini dapat dicapai menggunakanMediaSessionService Media3.

Membuat MediaSessionService

  1. Klik kanan pada paket com.example.android.cars.roadreels di jendela Project, lalu pilih New > Kotlin Class/File. Beri nama file PlaybackService, lalu klik jenis Class.
  2. Tambahkan implementasi PlaybackService. berikut. Lihat Pemutaran di latar belakang dengan MediaSessionService untuk mengetahui informasi selengkapnya tentang MediaSessionService.

PlaybackService.kt

import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService

@UnstableApi
class PlaybackService : MediaSessionService() {
    private var mediaSession: MediaSession? = null

    override fun onCreate() {
        super.onCreate()
        val player = RoadReelsPlayer(this)
        mediaSession = MediaSession.Builder(this, player).build()
    }

    override fun onDestroy() {
        mediaSession?.run {
            player.release()
            release()
            mediaSession = null
        }
        super.onDestroy()
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? {
        if (controllerInfo.isTrusted || controllerInfo.packageName == packageName) {
            return mediaSession
        }
        return null
    }
}
  1. Tambahkan elemen <uses-permission> berikut dalam file manifes. Pemutaran media ditangani menggunakan layanan latar depan

AndroidManifest.xml

<manifest ...>
    ...
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
    ...
</manifest>
  1. Deklarasikan juga PlaybackService dalam manifes:

AndroidManifest.xml

<application ...>
    ...
    <service
        android:name=".PlaybackService"
        android:foregroundServiceType="mediaPlayback"
        android:exported="true">
        <intent-filter>
            <action android:name="androidx.media3.session.MediaSessionService"/>
        </intent-filter>
    </service>
</application>

Memperbarui PlayerViewModel untuk menggunakan PlaybackService

  1. Karena PlaybackService membuat dan mengekspos MediaSession itu sendiri, PlayerViewModel tidak perlu lagi membuatnya. Temukan dan hapus baris berikut serta semua referensi ke variabel:

PlayerViewModel.kt

private var mediaSession: MediaSession? = null
  1. Selanjutnya, ganti bagian blok init yang membuat instance RoadReelsPlayer dengan kode berikut yang menghubungkan aplikasi ke PlaybackService menggunakan MediaController.

PlayerViewModel.kt

import android.content.ComponentName
import androidx.media3.session.MediaController
import androidx.media3.session.SessionToken
import com.example.android.cars.roadreels.PlaybackService
import com.google.common.util.concurrent.MoreExecutors

...

init {
        viewModelScope.launch {
            ...
        }
        
        val sessionToken = SessionToken(
            application,
            ComponentName(application, PlaybackService::class.java)
        )

        val mediaControllerFuture =
            MediaController.Builder(getApplication(), sessionToken).buildAsync()

        mediaControllerFuture.addListener(
            { _player.update { mediaControllerFuture.get() } },
            MoreExecutors.directExecutor()
        )
    }

Uji kembali aplikasi, dan Anda akan melihat UI yang berbeda muncul saat aplikasi tertutup oleh sistem. Sekarang, pengguna dapat mengontrol pemutaran saat mereka mengemudi. Dan saat kembali berhenti, mereka dapat mengklik tombol keluar untuk kembali ke pengalaman aplikasi lengkap.

33eb8ff3d4035978.gif

Menghapus perubahan pemutaran siklus proses

Karena pemutaran latar belakang kini didukung, Anda dapat menghapus dua blok LifecycleEventEffect di PlayerScreen.kt sehingga pemutaran dapat dilanjutkan saat pengguna keluar dari aplikasi, termasuk saat kontrol pemutaran yang ditampilkan di layar sebelumnya ditampilkan.

Menjeda pemutaran saat keluar dari layar pemutar

Karena pemutar sebenarnya (yang sekarang terdapat dalam PlaybackService) tidak dirilis saat keluar dari layar pemutar, Anda harus menambahkan panggilan untuk menjeda pemutaran saat keluar dari pemutar untuk sehingga perilaku sebelumnya dapat dipertahankan. Untuk melakukannya, Anda dapat memperbarui implementasi metode onCleared PlayerViewModel:

PlayerViewModel.kt

override fun onCleared() {
    super.onCleared()
    _player.value?.apply {
        pause()
        release()
    }
}

7. Memperbarui manifes

Terakhir, untuk menunjukkan bahwa aplikasi Anda mendukung audio saat mengemudi, Anda perlu menambahkan elemen <uses-feature> berikut dalam manifes aplikasi.

AndroidManifest.xml

<application>
    <uses-feature android:name="com.android.car.background_audio_while_driving" android:required="false">
</application>

8. Selamat

Anda berhasil menambahkan dukungan untuk audio saat mengemudi ke aplikasi video. Sekarang saatnya menerapkan apa yang telah Anda pelajari ke aplikasi Anda sendiri.

Bacaan lebih lanjut