Gunakan Instrument Cluster API (Android API) untuk menampilkan aplikasi navigasi, termasuk Google Maps, di layar sekunder di mobil, seperti di belakang setir pada panel instrumen. Halaman ini menjelaskan cara membuat layanan untuk mengontrol tampilan sekunder tersebut dan mengintegrasikan layanan dengan CarService sehingga aplikasi navigasi dapat menampilkan antarmuka pengguna.
Terminologi
Istilah berikut digunakan di halaman ini.
CarManager yang memungkinkan aplikasi eksternal meluncurkan aktivitas di
Klaster Instrumen dan menerima callback saat Klaster Instrumen siap menampilkan
aktivitas.android:singleUser. Setiap saat, paling banyak satu instance layanan berjalan di sistem Android.Prasyarat
Sebelum melanjutkan, pastikan Anda memiliki elemen berikut:
- Lingkungan pengembangan Android. Untuk menyiapkan lingkungan pengembangan Android, lihat Persyaratan build.
- Download kode sumber Android. Dapatkan versi terbaru kode sumber Android dari cabang pi-car-release (atau yang lebih baru) di https://android.googlesource.com.
- Head unit (HU). Perangkat Android yang dapat menjalankan Android 9 (atau yang lebih baru). Perangkat ini harus memiliki layarnya sendiri dan dapat mem-flash layar dengan build Android baru.
- Cluster Instrumen adalah salah satu dari berikut ini:
- Layar sekunder fisik yang terhubung ke HU. Jika hardware dan kernel perangkat mendukung pengelolaan beberapa tampilan.
- Unit terpisah. Unit komputasi apa pun yang terhubung ke HU melalui koneksi jaringan, yang dapat menerima dan menampilkan streaming video di layarnya sendiri.
- Tampilan yang diemulasi. Selama pengembangan, Anda dapat menggunakan salah satu
lingkungan yang diemulasi berikut:
- Simulasi tampilan sekunder. Untuk mengaktifkan tampilan sekunder simulasi di distribusi Android AOSP mana pun, buka setelan Opsi Developer di aplikasi sistem Setelan, lalu pilih Simulasikan tampilan sekunder. Konfigurasi ini setara dengan melampirkan tampilan sekunder fisik, dengan batasan bahwa tampilan ini ditumpangkan di atas tampilan utama.
- Cluster instrumen yang diemulasi. Emulator Android yang disertakan dengan AAOS menyediakan opsi untuk menampilkan panel instrumen dengan ClusterRenderingService.
Arsitektur integrasi
Komponen integrasi
Setiap integrasi Instrument Cluster API terdiri dari tiga komponen berikut:
CarService- Aplikasi navigasi
- Layanan Cluster Instrumen OEM

LayananMobil
CarService memediasi antara aplikasi navigasi dan mobil, memastikan bahwa hanya
satu aplikasi navigasi yang aktif pada waktu tertentu dan hanya aplikasi dengan izin
android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL yang dapat mengirim data
ke mobil.
CarService mem-bootstrap semua layanan khusus mobil dan menyediakan akses ke
layanan ini melalui serangkaian pengelola. Untuk berinteraksi dengan layanan, aplikasi yang berjalan di mobil dapat mengakses pengelola ini.
Untuk penerapan cluster instrumen, OEM otomotif harus membuat penerapan kustom InstrumentClusterRendererService dan mengupdate ClusterRenderingService.
Saat merender Kluster Instrumen, selama proses booting, CarService akan membaca kunci InstrumentClusterRendererService dari
ClusterRenderingService
untuk menemukan penerapan InstrumentClusterService. Di AOSP, entri ini mengarah ke layanan rendering penerapan cluster contoh Navigation State API:
<string name="instrumentClusterRendererService"> android.car.cluster/.ClusterRenderingService </string>
Layanan yang dirujuk dalam entri ini diinisialisasi dan terikat ke
CarService. Saat aplikasi navigasi, seperti Google Maps, meminta
CarInstrumentClusterManager, CarService menyediakan pengelola yang
memperbarui status Cluster Instrumen dari InstrumentClusterRenderingService terikat.
(Dalam hal ini, terikat merujuk pada
Layanan
Android.)
Layanan Instrument Cluster
OEM harus membuat Paket Android (APK) yang berisi subclass ClusterRenderingService.
Class ini memiliki dua tujuan:
- Menyediakan antarmuka Android dan perangkat rendering Cluster Instrumen (tujuan halaman ini).
- Menerima dan merender update status navigasi, seperti panduan navigasi belokan demi belokan.
Untuk tujuan pertama, implementasi OEM InstrumentClusterRendererService harus menginisialisasi layar sekunder yang digunakan untuk merender informasi di layar dalam kabin mobil dan mengomunikasikan informasi ini ke CarService dengan memanggil metode InstrumentClusterRendererService.setClusterActivityOptions() dan InstrumentClusterRendererService.setClusterActivityState().
Untuk fungsi kedua, layanan Instrument Cluster harus menyediakan penerapan
antarmuka ClusterRenderingService
yang menerima peristiwa update status navigasi, yang dienkode sebagai
eventType dan data peristiwa yang dienkode dalam paket.
Urutan integrasi
Diagram berikut mengilustrasikan implementasi status navigasi yang merender update:
Dalam ilustrasi ini, warna menunjukkan hal berikut:
- Kuning.
CarServicedanCarNavigationStatusManageryang disediakan oleh platform Android. Untuk mempelajari lebih lanjut, lihat Car dan CAR_NAVIGATION_SERVICE. - Sian.
InstrumentClusterRendererServicediterapkan oleh OEM. - Ungu. Aplikasi Navigasi yang diterapkan oleh Google dan developer pihak ketiga.
- Hijau.
CarAppFocusManager. Untuk mempelajari lebih lanjut, lihat Menggunakan CarAppFocusManager API di bawah dan CarAppFocusManager.
Alur informasi Status Navigasi mengikuti urutan berikut:
CarServicemelakukan inisialisasiInstrumentClusterRenderingService.- Selama inisialisasi,
InstrumentClusterRenderingServicememperbaruiCarServicedengan:- Properti tampilan Cluster Instrumen, seperti batas yang tidak terhalang (lihat detail selengkapnya tentang batas yang tidak terhalang nanti).
- Opsi aktivitas yang diperlukan untuk meluncurkan aktivitas di dalam tampilan Kluster Instrumen. Untuk mempelajari lebih lanjut, lihat ActivityOptions.
- Aplikasi navigasi (seperti Google Maps untuk Android Automotive atau aplikasi peta apa pun dengan izin yang diperlukan):
- Mendapatkan
CarAppFocusManagermenggunakan class Car dari car-lib. - Sebelum panduan belokan demi belokan dimulai, panggilan ke
CarAppFocusManager.requestFocus()untuk meneruskanCarAppFocusManager.APP_FOCUS_TYPE_NAVIGATIONsebagai parameterappType.
- Mendapatkan
CarAppFocusManagermengomunikasikan permintaan ini kepadaCarService. Jika diizinkan,CarServiceakan memeriksa paket aplikasi navigasi dan menemukan aktivitas yang ditandai dengan kategoriandroid.car.cluster.NAVIGATION.- Jika ditemukan, aplikasi navigasi menggunakan
ActivityOptionsyang dilaporkan olehInstrumentClusterRenderingServiceuntuk meluncurkan aktivitas dan menyertakan properti tampilan Cluster Instrumen sebagai ekstra dalam intent.
Mengintegrasikan API
Implementasi InstrumentClusterRenderingService harus:
- Ditetapkan sebagai layanan singleton dengan menambahkan nilai berikut ke
AndroidManifest.xml. Hal ini diperlukan untuk memastikan bahwa satu salinan layanan
Instrument Cluster berjalan, bahkan selama inisialisasi dan peralihan pengguna:
android:singleUser="true" - Pegang izin sistem
BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE. Hal ini menjamin bahwa hanya layanan rendering Cluster Instrumen yang disertakan sebagai bagian dari image sistem Android yang pernah terikat olehCarService:<uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
Menerapkan InstrumentClusterRenderingService
Untuk membangun layanan:
- Tulis class yang diperluas dari
ClusterRenderingService
lalu tambahkan entri yang sesuai ke file
AndroidManifest.xmlAnda. Class ini mengontrol tampilan Cluster Instrumen dan dapat (opsional) merender data API Status Navigasi. - Selama
onCreate(), gunakan layanan ini untuk melakukan inisialisasi komunikasi dengan hardware rendering. Opsinya mencakup:- Tentukan tampilan sekunder yang akan digunakan untuk Cluster Instrumen.
- Buat tampilan virtual sehingga aplikasi Instrument Cluster merender dan mengirimkan gambar yang dirender ke unit eksternal (menggunakan format streaming video, seperti H.264).
- Saat layar yang disebutkan di atas siap, layanan ini harus memanggil
InstrumentClusterRenderingService#setClusterActivityLaunchOptions()untuk menentukanActivityOptionspersisnya yang harus digunakan untuk menampilkan Aktivitas di Cluster Instrumen. Gunakan parameter ini:category.ClusterRenderingService.ActivityOptions.InstanceActivityOptionsyang dapat digunakan untuk meluncurkan Aktivitas di Kluster Instrumen. Misalnya, dari implementasi Instrument Cluster sampel di AOSP:getService().setClusterActivityLaunchOptions( CATEGORY_NAVIGATION, ActivityOptions.makeBasic() .setLaunchDisplayId(displayId));
- Saat Cluster Instrumen siap menampilkan aktivitas, layanan ini harus memanggil
InstrumentClusterRenderingService#setClusterActivityState(). Gunakan parameter berikut:categoryClusterRenderingService.stateBundle dibuat dengan ClusterRenderingService. Pastikan untuk memberikan data ini:visibleMenentukan Klaster Instrumen sebagai terlihat dan siap menampilkan konten.unobscuredBoundsPersegi panjang yang menentukan area dalam tampilan Cluster Instrumen yang aman untuk menampilkan konten. Misalnya, area yang dicakup oleh kenop dan pengukur.
- Ganti metode
Service#dump()dan laporkan informasi status yang berguna untuk pen-debug-an (lihat dumpsys untuk mengetahui informasi selengkapnya).
Contoh penerapan InstrumentClusterRenderingService
Contoh berikut menguraikan implementasi InstrumentClusterRenderingService, yang membuat VirtualDisplay untuk menampilkan konten Instrument Cluster pada layar fisik jarak jauh.
Atau, kode ini dapat meneruskan displayId dari layar sekunder fisik yang terhubung ke HU, jika diketahui tersedia.
/** * Sample {@link InstrumentClusterRenderingService} implementation */ public class SampleClusterServiceImpl extends InstrumentClusterRenderingService { // Used to retrieve or create displays private final DisplayManager mDisplayManager; // Unique identifier for the display to be used for instrument // cluster private final String mUniqueId = UUID.randomUUID().toString(); // Format of the instrument cluster display private static final int DISPLAY_WIDTH = 1280; private static final int DISPLAY_HEIGHT = 720; private static final int DISPLAY_DPI = 320; // Area not covered by instruments private static final int DISPLAY_UNOBSCURED_LEFT = 40; private static final int DISPLAY_UNOBSCURED_TOP = 0; private static final int DISPLAY_UNOBSCURED_RIGHT = 1200; private static final int DISPLAY_UNOBSCURED_BOTTOM = 680; @Override public void onCreate() { super.onCreate(); // Create a virtual display to render instrument cluster activities on mDisplayManager = getSystemService(DisplayManager.class); VirtualDisplay display = mDisplayManager.createVirtualDisplay( mUniqueId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DPI, null, 0 /* flags */, null, null); // Do any additional initialization (e.g.: start a video stream // based on this virtual display to present activities on a remote // display). onDisplayReady(display.getDisplay()); } private void onDisplayReady(Display display) { // Report activity options that should be used to launch activities on // the instrument cluster. String category = CarInstrumentClusterManager.CATEGORY_NAVIGATION; ActionOptions options = ActivityOptions.makeBasic() .setLaunchDisplayId(display.getDisplayId()); setClusterActivityOptions(category, options); // Report instrument cluster state. Rect unobscuredBounds = new Rect(DISPLAY_UNOBSCURED_LEFT, DISPLAY_UNOBSCURED_TOP, DISPLAY_UNOBSCURED_RIGHT, DISPLAY_UNOBSCURED_BOTTOM); boolean visible = true; ClusterActivityState state = ClusterActivityState.create(visible, unobscuredBounds); setClusterActivityState(category, options); } }
Menggunakan CarAppFocusManager API
CarAppFocusManager API menyediakan metode bernama getAppTypeOwner(), yang memungkinkan
layanan cluster yang ditulis oleh OEM mengetahui aplikasi navigasi mana yang memiliki fokus navigasi pada waktu tertentu. OEM dapat menggunakan metode CarAppFocusManager#addFocusListener() yang ada, lalu menggunakan getAppTypeOwner() untuk mempelajari aplikasi mana yang memiliki fokus. Dengan informasi ini, OEM dapat:
- Mengalihkan aktivitas yang ditampilkan di cluster ke aktivitas cluster yang disediakan oleh aplikasi navigasi yang memiliki fokus.
- Dapat mendeteksi apakah aplikasi navigasi yang difokuskan memiliki aktivitas cluster atau tidak. Jika aplikasi navigasi yang difokuskan tidak memiliki aktivitas cluster (atau jika aktivitas tersebut dinonaktifkan), OEM dapat mengirim sinyal ini ke DIM mobil sehingga aspek navigasi cluster dilewati sepenuhnya.
Gunakan CarAppFocusManager untuk menyetel dan mendengarkan fokus aplikasi saat ini, seperti
navigasi aktif atau perintah suara. Biasanya hanya ada satu instance aplikasi tersebut yang berjalan (atau difokuskan) secara aktif dalam sistem.
Gunakan metode CarAppFocusManager#addFocusListener(..) untuk memantau perubahan fokus aplikasi:
import android.car.CarAppFocusManager; ... Car car = Car.createCar(this); mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE); mAppFocusManager.addFocusListener(this, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); ... public void onAppFocusChanged(int appType, boolean active) { // Use the CarAppFocusManager#getAppTypeOwner(appType) method call // to retrieve a list of active package names }
Gunakan metode CarAppFocusManager#getAppTypeOwner(..) untuk mengambil nama paket pemilik saat ini dari jenis aplikasi tertentu yang menjadi fokus. Metode ini dapat menampilkan
lebih dari satu nama paket jika pemilik saat ini menggunakan fitur android:sharedUserId.
import android.car.CarAppFocusManager; ... Car car = Car.createCar(this); mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE); List<String> focusOwnerPackageNames = mAppFocusManager.getAppTypeOwner( CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); if (focusOwnerPackageNames == null || focusOwnerPackageNames.isEmpty()) { // No Navigation app has focus // OEM may choose to show their default cluster view } else { // focusOwnerPackageNames // Use the PackageManager to retrieve the cluster activity for the package(s) // returned in focusOwnerPackageNames } ...
Mengidentifikasi aplikasi template
Untuk aplikasi navigasi berbasis template yang menggunakan library Aplikasi Mobil,
CarAppFocusManager#getAppTypeOwner() menampilkan nama paket host
(misalnya, com.google.android.apps.automotive.templates.host)
karena host memegang fokus sistem atas nama aplikasi klien.
Untuk mengidentifikasi aplikasi klien yang melakukan navigasi, OEM dapat mengekstrak nama paket dari paket status navigasi yang dikirim dengan CarNavigationStatusManager. Nama paket disimpan dengan
kunci active_app_package_name dalam paket yang diterima oleh
NavigationRenderer#onNavigationStateChanged(Bundle):
// In your NavigationRenderer implementation @Override public void onNavigationStateChanged(Bundle bundle) { if (bundle.containsKey("active_app_package_name")) { String activeAppPackage = bundle.getString("active_app_package_name"); // Use the package name to identify the navigating app (e.g., com.waze) } }
Lampiran: Menggunakan aplikasi contoh
AOSP menyediakan aplikasi contoh yang menerapkan Navigation State API.
Untuk menjalankan aplikasi contoh ini:
- Bangun dan flash Android Auto di HU yang didukung. Gunakan petunjuk pembuatan dan flashing Android yang khusus untuk perangkat Anda. Untuk mengetahui petunjuknya, lihat Menggunakan Papan Referensi.
- Hubungkan layar sekunder fisik ke HU (jika didukung) atau aktifkan HU sekunder
virtual:
- Pilih Mode Developer di aplikasi Setelan.
- Buka Setelan > Sistem > Lanjutan > Opsi developer > Simulasikan tampilan sekunder.
- Mulai ulang HU
- Untuk meluncurkan aplikasi KitchenSink:
- Buka laci.
- Buka Inst. Cluster.
- Klik MULAI METADATA.
KitchenSink meminta fokus NAVIGASI, yang menginstruksikan layanan DirectRenderingCluster
untuk menampilkan antarmuka pengguna tiruan di Cluster Instrumen.