Mem-build aplikasi navigasi, parkir, dan pengisian daya untuk Android Auto.

Library Aplikasi Android untuk Mobil memungkinkan Anda menghadirkan aplikasi navigasi, parkir, dan pengisian daya ke mobil. Hal ini dilakukan dengan menyediakan serangkaian template yang dirancang untuk memenuhi standar gangguan bagi pengemudi dan menangani detail seperti berbagai faktor layar mobil dan modalitas input.

Panduan ini menyediakan ringkasan fitur dan konsep utama library, dan memandu Anda dalam proses menyiapkan aplikasi sederhana.

Sebelum memulai

  1. Tinjau Pedoman Desain Library Aplikasi Android untuk Mobil.
  2. Pelajari istilah dan konsep utama yang tercantum dalam bagian ini.
  3. Biasakan diri Anda dengan UI Sistem Android Auto.
  4. Tinjau Catatan Rilis.
  5. Tinjau Contoh.
  6. [Hanya library sumber tertutup] Tinjau Persyaratan Penggunaan Library Aplikasi Android untuk Mobil.

Istilah dan konsep utama

Model dan Template
Antarmuka pengguna diwakili oleh grafik objek model yang dapat digabungkan dalam cara yang berbeda-beda seperti yang diizinkan oleh template yang mencakupnya. Template adalah subset model yang dapat bertindak sebagai root dalam grafik tersebut. Model mencakup informasi yang akan ditampilkan kepada pengguna, dalam bentuk teks dan gambar, serta atribut untuk mengonfigurasi aspek tampilan visual dari informasi tersebut (misalnya, warna teks atau ukuran gambar). Host mengonversi model ke tampilan yang dirancang untuk memenuhi standar gangguan bagi pengemudi dan menangani detail seperti berbagai faktor layar mobil dan modalitas input.
Host
Host adalah komponen back end yang menerapkan fungsi yang ditawarkan oleh API library agar aplikasi Anda dapat berjalan di mobil. Tanggung jawab host berkisar dari menemukan aplikasi dan mengelola siklus prosesnya, hingga mengubah model Anda menjadi tampilan dan memberi tahu aplikasi Anda tentang interaksi pengguna. Pada perangkat seluler, host ini diimplementasikan oleh Android Auto.
Batasan template
Berbagai template menerapkan pembatasan pada konten model mereka. Misalnya, template daftar memiliki batas jumlah item yang dapat ditampilkan kepada pengguna. Template juga memiliki batasan agar dapat dihubungkan untuk membuat alur tugas. Misalnya, aplikasi hanya dapat mendorong hingga 5 template ke stack layar. Lihat Batasan template untuk detail selengkapnya.
Layar
Screen adalah class yang disediakan oleh library yang diterapkan aplikasi untuk mengelola antarmuka pengguna yang ditampilkan kepada pengguna. Screen memiliki lifecycle dan menyediakan mekanisme bagi aplikasi untuk mengirim template agar ditampilkan saat layar terlihat. Instance Screen juga dapat didorong dan muncul ke dan dari Stack layar, yang memastikannya mematuhi pembatasan alur template.
CarAppService
CarAppService adalah class Service abstrak yang harus diterapkan dan diekspor aplikasi Anda agar dapat ditemukan dan dikelola oleh host. CarAppService aplikasi Anda bertanggung jawab untuk memvalidasi bahwa koneksi host dapat dipercaya menggunakan CarAppService.createHostValidator, dan kemudian menyediakan instance Session untuk setiap sambungan menggunakan CarAppService.onCreateSession.
Sesi
Session adalah class abstrak yang harus diterapkan dan ditampilkan oleh aplikasi Anda menggunakan CarAppService.onCreateSession. Ini berfungsi sebagai titik masuk untuk menampilkan informasi di layar mobil, dan memiliki siklus hidup yang menginformasikan status aplikasi saat ini di layar mobil, seperti saat aplikasi Anda terlihat atau tersembunyi.

Saat Session dimulai (seperti saat aplikasi pertama kali diluncurkan), host akan meminta Screen awal untuk ditampilkan menggunakan metode Session.onCreateScreen.

Menginstal library

Ikuti halaman rilis library Jetpack untuk mendapatkan petunjuk tentang cara menambahkan library ke aplikasi Anda.

Mengonfigurasi file manifes aplikasi Anda

Sebelum dapat membuat aplikasi mobil, Anda perlu mengonfigurasi file manifes aplikasi Anda.

Mendeklarasikan CarAppService Anda

Host terhubung ke aplikasi Anda melalui penerapan CarAppService. Anda mendeklarasikan layanan ini dalam manifes agar host dapat menemukan dan terhubung ke aplikasi Anda.

Anda juga harus mendeklarasikan kategori aplikasi Anda dalam elemen category dari filter intent aplikasi Anda. Lihat daftar kategori aplikasi yang didukung untuk nilai yang diizinkan untuk elemen ini.

Cuplikan kode berikut ini menunjukkan cara mendeklarasikan layanan aplikasi mobil untuk aplikasi parkir di manifes Anda:

<application>
    ...
   <service
       ...
        android:name=".MyCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService"/>
        <category android:name="androidx.car.app.category.PARKING"/>
      </intent-filter>
    </service>

    ...
<application>

Kategori Aplikasi yang Didukung

Agar tercantum di Play Store untuk Android Auto, aplikasi harus termasuk dalam salah satu kategori aplikasi mobil yang didukung. Anda mendeklarasikan kategori aplikasi dengan menambahkan satu atau beberapa nilai kategori yang didukung berikut di filter intent saat mendeklarasikan layanan aplikasi mobil:

  • androidx.car.app.category.NAVIGATION: Aplikasi yang menyediakan petunjuk arah navigasi belokan demi belokan.
  • androidx.car.app.category.PARKING: Aplikasi yang menyediakan fungsi yang relevan untuk menemukan tempat parkir.
  • androidx.car.app.category.CHARGING: Aplikasi yang menyediakan fungsi yang relevan untuk menemukan Stasiun Pengisian Kendaraan Listrik Umum.

Lihat Kualitas aplikasi Android untuk mobil guna mengetahui deskripsi dan kriteria terperinci untuk aplikasi yang termasuk dalam setiap kategori.

Menentukan nama dan ikon aplikasi

Anda perlu menentukan nama dan ikon aplikasi yang dapat digunakan oleh host untuk mewakili aplikasi Anda di UI sistem.

Anda dapat menentukan nama dan ikon aplikasi yang digunakan untuk mewakili aplikasi menggunakan elemen label dan icon dari CarAppService:

...
<service
   android:name=".MyCarAppService"
   android:exported="true"
   android:label="@string/my_app_name"
   android:icon="@drawable/my_app_icon">
   ...
</service>
...

Jika label atau ikon tidak dideklarasikan dalam elemen service, host akan kembali ke nilai yang ditentukan untuk aplikasi tersebut.

Menetapkan minSdkVersion aplikasi Anda

Android Auto mengharuskan aplikasi Anda menargetkan Android 6.0 (API level 23) atau yang lebih tinggi.

Untuk menentukan nilai ini dalam project Anda, setel atribut minSdkVersion di elemen uses-sdk ke 23 atau lebih tinggi di file AndroidManifest.xml modul aplikasi ponsel, seperti yang ditunjukkan dalam contoh berikut:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ... >
    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="23" />
    ...
</manifest>

Mendeklarasikan dukungan Android Auto

Host Android Auto memeriksa apakah aplikasi telah mendeklarasikan dukungan untuk Android Auto. Untuk memungkinkan dukungan ini, sertakan entri berikut dalam manifes aplikasi Anda:

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

Entri manifes ini mengacu pada file XML lain yang harus Anda buat dengan YourAppProject/app/src/main/res/xml/automotive_app_desc.xml jalur yang digunakan untuk mendeklarasikan kemampuan Android Auto yang didukung aplikasi Anda.

Aplikasi yang menggunakan Library Aplikasi Android untuk Mobil harus menyatakan kemampuan template dalam file automotive_app_desc.xml:

<automotiveApp>
    <uses name="template" />
</automotiveApp>

Membuat CarAppService dan Sesi

Aplikasi Anda perlu memperluas class CarAppService dan menerapkan metode CarAppService.onCreateSession, yang menampilkan instance Session yang sesuai ke koneksi saat ini ke host:

public final class HelloWorldService extends CarAppService {
  ...
  @Override
  @NonNull
  public Session onCreateSession() {
    return new HelloWorldSession();
  }
  ...
}

Instance Session bertanggung jawab untuk mengembalikan instance Screen untuk digunakan saat aplikasi pertama kali dimulai:

public final class HelloWorldSession extends Session {
  ...
  @Override
  @NonNull
  public Screen onCreateScreen(@NonNull Intent intent) {
    return new HelloWorldScreen();
  }
  ...
}

Untuk menangani skenario saat aplikasi mobil harus dimulai dari layar yang bukan layar utama atau halaman landing aplikasi (seperti menangani deep link), Anda dapat melakukan pra-seed data layar sebelumnya menggunakan ScreenManager.push. sebelum kembali dari onCreateScreen. Pra-seeding memungkinkan pengguna kembali ke layar sebelumnya dari layar pertama yang ditampilkan aplikasi Anda.

Membuat layar mulai

Anda membuat layar yang ditampilkan oleh aplikasi dengan menentukan kelas yang memperluas class Screen dan menerapkan metode Screen.onGetTemplate, yang menampilkan instance Template yang mewakili status UI untuk ditampilkan di layar mobil.

Cuplikan berikut menunjukkan cara mendeklarasikan Screen yang menggunakan template PaneTemplate untuk menampilkan string “Halo dunia!” yang sederhana:

public class HelloWorldScreen extends Screen {
  @NonNull
  @Override
  public Template onGetTemplate() {
    Pane pane = new Pane.Builder()
        .addRow(new Row.Builder()
            .setTitle("Hello world!")
            .build())
        .build();
    return new PaneTemplate.Builder(pane)
            .setHeaderAction(Action.APP_ICON)
            .build();
  }
}

Class CarContext

Class CarContext adalah subclass ContextWrapper yang bisa diakses oleh instance Session dan Screen, yang memberikan akses ke layanan mobil seperti ScreenManager untuk mengelola stack layar ,AppManager untuk fungsi terkait aplikasi umum seperti mengakses objek Surface untuk menggambar peta aplikasi navigasi Anda, dan NavigationManager yang digunakan oleh aplikasi navigasi belokan demi belokan untuk menyampaikan metadata navigasi dan peristiwa terkait navigasi lainnya dengan host. Lihat Mengakses template navigasi untuk daftar lengkap fungsi library yang tersedia untuk aplikasi navigasi.

CarContext juga menawarkan fungsi lain seperti mengizinkan pemuatan resource drawable menggunakan konfigurasi dari layar mobil, memulai aplikasi di mobil menggunakan intent, dan memberi sinyal apakah aplikasi navigasi Anda harus menampilkan petanya dalam mode gelap.

Menerapkan navigasi layar

Aplikasi sering kali menyajikan sejumlah layar yang berbeda, masing-masing mungkin menggunakan template yang berbeda, yang dapat dilihat pengguna saat mereka berinteraksi dengan antarmuka yang ditampilkan di layar.

Class ScreenManager menyediakan stack layar yang dapat Anda gunakan untuk mendorong layar yang dapat muncul secara otomatis saat pengguna memilih tombol kembali di layar mobil, atau menggunakan atribut tombol kembali hardware yang tersedia di beberapa mobil.

Cuplikan berikut menunjukkan cara menambahkan tindakan kembali ke template pesan, serta tindakan yang mendorong layar baru saat dipilih oleh pengguna:

MessageTemplate template = new MessageTemplate.Builder("Hello world!")
    .setHeaderAction(Action.BACK)
    .addAction(
        new Action.Builder()
            .setTitle("Next screen")
            .setOnClickListener(() -> getScreenManager().push(new NextScreen()))
            .build())
    .build();

Objek Action.BACK adalah Action standar yang secara otomatis memanggil ScreenManager.pop. Perilaku ini dapat diganti dengan menggunakan instance OnBackPressedDispatcher yang tersedia dari CarContext.

Untuk memastikan aplikasi aman saat mengemudi, stack layar dapat memiliki kedalaman maksimum 5 layar. Lihat Pembatasan template untuk mengetahui detail selengkapnya.

Memuat ulang konten template

Aplikasi Anda dapat meminta konten Screen agar dijadikan tidak valid dengan memanggil metode Screen.invalidate. Host kemudian memanggil kembali ke metode Screen.onGetTemplate aplikasi untuk mengambil template dengan konten baru.

Saat memuat ulang Screen, penting untuk memahami konten tertentu dalam template yang dapat diperbarui sehingga host tidak akan memperhitungkan template baru dalam kuota template. Lihat Batasan template untuk detail selengkapnya.

Sebaiknya buat struktur layar Anda sehingga ada pemetaan one-to-one antara Screen dan jenis template yang ditampilkan melalui implementasi Screen.onGetTemplate.

Menangani input pengguna

Aplikasi Anda dapat merespons input pengguna dengan meneruskan pendengar yang sesuai ke model yang mendukung mereka. Cuplikan berikut menunjukkan cara membuat model Action yang menyetel OnClickListener yang dipanggil kembali ke metode yang ditentukan dengan kode aplikasi Anda:

Action action = new Action.Builder()
    .setTitle("Navigate")
    .setOnClickListener(this::onClickNavigate)
    .build();

Metode onClickNavigate kemudian dapat memulai aplikasi mobil navigasi default dengan menggunakan metode CarContext.startCarApp:

private void onClickNavigate() {
  Intent intent = new Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address));
  getCarContext().startCarApp(intent);
}

Untuk detail selengkapnya tentang cara memulai aplikasi, termasuk format intent ACTION_NAVIGATE, lihat Memulai aplikasi mobil dengan intent.

Beberapa tindakan, seperti tindakan yang mengharuskan pengguna melanjutkan interaksi di perangkat seluler, hanya diizinkan saat mobil diparkir. Anda dapat menggunakan ParkedOnlyOnClickListener untuk menerapkan tindakan tersebut. Jika mobil tidak diparkir, host akan menampilkan indikasi kepada pengguna bahwa tindakan tersebut tidak diizinkan dalam kasus ini. Jika mobil diparkir, kode akan dijalankan seperti biasa. Cuplikan berikut menunjukkan cara menggunakan ParkedOnlyOnClickListener untuk membuka layar setelan di perangkat seluler:

Row row = new Row.Builder()
    .setTitle("Open Settings")
    .setOnClickListener(
        ParkedOnlyOnClickListener.create(this::openSettingsOnPhone)
    .build();

Menampilkan notifikasi

Notifikasi yang dikirim ke perangkat seluler hanya akan muncul di layar mobil jika notifikasi tersebut diperluas dengan CarAppExtender. Beberapa atribut notifikasi, seperti judul konten, teks, ikon, dan tindakan, dapat ditetapkan di CarAppExtender, menggantikan atribut notifikasi saat muncul di layar mobil.

Cuplikan berikut menunjukkan cara mengirim notifikasi ke layar mobil yang menampilkan judul yang berbeda dari yang ditampilkan di perangkat seluler:

Notification notification =
    new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
        .setContentTitle(titleOnThePhone)
        .extend(
            new CarAppExtender.Builder()
                .setContentTitle(titleOnTheCar)
                ...
                .build())
        .build();

Notifikasi dapat memengaruhi bagian antarmuka pengguna berikut:

  • Notifikasi pendahuluan (HUN) dapat ditampilkan kepada pengguna.
  • Entri di pusat notifikasi dapat ditambahkan, secara opsional dengan badge yang terlihat di rel.
  • Untuk aplikasi navigasi, notifikasi dapat ditampilkan di widget rel seperti yang dijelaskan dalam Notifikasi belokan demi belokan.

Aplikasi dapat memilih cara mengonfigurasi notifikasi untuk memengaruhi setiap elemen antarmuka pengguna dengan menggunakan prioritas notifikasi, seperti yang dijelaskan dalam dokumentasi CarAppExtender.

Jika NotificationCompat.Builder.setOnlyAlertOnce dipanggil dengan nilai true, notifikasi prioritas tinggi hanya akan ditampilkan sebagai HUN satu kali.

Untuk mengetahui informasi selengkapnya tentang cara mendesain notifikasi aplikasi mobil, lihat Notifikasi.

Menampilkan toast

Aplikasi Anda dapat menampilkan toast menggunakan CarToast seperti yang ditunjukkan dalam cuplikan ini:

CarToast.makeText(getCarContext(), "Hello!", CarToast.LENGTH_SHORT).show();

Memulai aplikasi mobil dengan intent

Anda dapat memanggil metode CarContext.startCarApp untuk melakukan salah satu tindakan berikut:

  • Buka telepon untuk menelepon.
  • Mulai navigasi belokan demi belokan ke lokasi dengan aplikasi mobil navigasi default.
  • Mulai aplikasi Anda sendiri dengan intent.

Contoh berikut menunjukkan cara membuat notifikasi dengan tindakan yang membuka aplikasi Anda dengan layar yang menampilkan detail reservasi parkir. Anda memperluas instance notifikasi dengan intent konten yang berisi PendingIntent yang menggabungkan intent eksplisit ke tindakan aplikasi Anda:

Notification notification =
    notificationBuilder.
        …
        .extend(
            new CarAppExtender.Builder()
                .setContentIntent(
                    PendingIntent.getBroadcast(
                        context,
                        ACTION_VIEW_PARKING_RESERVATION.hashCode(),
                        new Intent(ACTION_VIEW_PARKING_RESERVATION)
                            .setComponent(
                                new ComponentName(context, MyNotificationReceiver.class)),
                        0))
                .build())

Aplikasi Anda juga harus mendeklarasikan BroadcastReceiver yang dipanggil untuk memproses intent saat pengguna memilih tindakan dalam antarmuka notifikasi dan memanggil CarContext.startCarApp dengan intent termasuk URI data:

public class MyNotificationReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
    String intentAction = intent.getAction();
    if (ACTION_VIEW_PARKING_RESERVATION.equals(intentAction)) {
      CarContext.startCarApp(
         intent,
          new Intent(Intent.ACTION_VIEW)
              .setComponent(new ComponentName(context, MyCarAppService.class))
              .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction)));
    }
  }
}

Terakhir, metode Session.onNewIntent di aplikasi Anda menangani intent ini dengan mendorong layar reservasi parkir di stack jika belum ada di bagian atas:

@Override
public void onNewIntent(@NonNull Intent intent) {
  Uri uri = intent.getData();
  if (uri != null
      && MY_URI_SCHEME.equals(uri.getScheme())
      && MY_URI_HOST.equals(uri.getSchemeSpecificPart())
      && ACTION_VIEW_PARKING_RESERVATION.equals(uri.getFragment())) {

    Screen top = screenManager.getTop();
    if (!(top instanceof ParkingReservationScreen)) {
      ScreenManager screenManager = getCarContext().getCarService(ScreenManager.class);
      screenManager.push(new ParkingReservationScreen(getCarContext()));
    }
  }
}

Lihat Notifikasi tampilan untuk mengetahui informasi selengkapnya tentang cara menangani notifikasi untuk aplikasi mobil.

Batasan template

Host membatasi jumlah template yang ditampilkan untuk tugas yang diberikan hingga maksimum 5 template, dengan template terakhir harus salah satu dari jenis berikut:

  1. NavigationTemplate
  2. PaneTemplate
  3. MessageTemplate

Perhatikan bahwa batas ini berlaku untuk jumlah template, dan bukan jumlah instance Screen dalam stack. Misalnya, jika di layar A aplikasi mengirimkan 2 template, lalu mendorong layar B, aplikasi kini dapat mengirim 3 template lainnya. Atau, jika setiap layar disusun untuk mengirim satu template, aplikasi dapat mendorong 5 instance layar ke stack ScreenManager.

Ada beberapa kasus khusus pada pembatasan ini: muat ulang template, operasi kembali, dan reset.

Memuat ulang template

Pembaruan konten tertentu tidak termasuk dalam batas template. Secara umum, selama aplikasi mendorong template baru dengan jenis yang sama dan berisi konten utama yang sama seperti template sebelumnya, template baru tidak akan mengurangi kuota. Misalnya, memperbarui status pengalihan baris dalam ListTemplate tidak mengurangi kuota. Baca dokumentasi setiap template untuk mempelajari lebih lanjut jenis pembaruan konten yang dapat dianggap sebagai pemuatan ulang.

Operasi kembali

Untuk mengaktifkan sub-aliran dalam tugas, host mendeteksi kapan aplikasi memunculkan Screen dari stack ScreenManager, dan memperbarui kuota yang tersisa berdasarkan pada jumlah template yang digunakan aplikasi untuk mundur.

Misalnya, jika saat berada di layar A, aplikasi mengirimkan 2 template, lalu mendorong layar B dan mengirim 2 template lainnya, aplikasi memiliki 1 kuota yang tersisa. Jika aplikasi sekarang muncul kembali ke layar A, host akan mereset kuota menjadi 3, karena aplikasi telah mundur sebanyak 2 template.

Perhatikan bahwa saat muncul kembali ke layar, aplikasi harus mengirim template dengan jenis yang sama dengan yang terakhir dikirim oleh layar tersebut. Mengirim jenis template lainnya akan menyebabkan error. Namun, selama jenisnya tetap sama selama operasi kembali, aplikasi dapat dengan bebas mengubah konten template tanpa memengaruhi kuota.

Operasi reset

Template tertentu memiliki semantik khusus yang menandakan akhir tugas. Misalnya, NavigationTemplate adalah tampilan yang diharapkan tetap ada di layar dan dimuat ulang dengan petunjuk belokan demi belokan untuk dipakai pengguna selama beberapa bulan. Setelah mencapai salah satu template ini, host akan mereset kuota template, memperlakukan template seolah-olah itu adalah langkah pertama dari tugas baru, sehingga aplikasi dapat memulai tugas baru. Lihat dokumentasi setiap template untuk melihat template mana yang memicu reset di host.

Jika host menerima maksud untuk memulai aplikasi dari tindakan notifikasi atau dari peluncur, kuota juga akan direset. Mekanisme ini memungkinkan aplikasi memulai alur tugas baru dari notifikasi, dan tetap berlaku meskipun aplikasi sudah terikat dan berada di latar depan.

Lihat Tampilkan notifikasi untuk detail selengkapnya tentang cara menampilkan notifikasi aplikasi di layar mobil, dan Mulai aplikasi mobil dengan intent untuk cara memulai aplikasi dari tindakan notifikasi.

Membuat aplikasi parkir atau pengisian daya

Bagian ini menjelaskan berbagai fitur library yang dapat Anda manfaatkan untuk menerapkan fungsi aplikasi parkir atau pengisian daya.

Mendeklarasikan dukungan kategori dalam manifes Anda

Aplikasi Anda perlu mendeklarasikan kategori aplikasi mobil androidx.car.app.category.PARKING atau androidx.car.app.category.CHARGING dalam filter intent CarAppService. Contoh:

<application>
    ...
   <service
       ...
        android:name=".MyCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.PARKING"/>
      </intent-filter>
    </service>
    ...
<application>

Mengakses template peta

Aplikasi dapat mengakses PlaceListMapTemplate yang dirancang khusus untuk menampilkan daftar lokasi menarik bersama peta yang dirender oleh host.

Untuk mendapatkan akses ke template ini, aplikasi Anda harus mendeklarasikan izin androidx.car.app.MAP_TEMPLATES di AndroidManifest.xml:

<uses-permission android:name="androidx.car.app.MAP_TEMPLATES"/>

Membuat aplikasi navigasi

Bagian ini menjelaskan berbagai fitur library yang dapat Anda manfaatkan untuk menerapkan fungsi aplikasi navigasi belokan demi belokan.

Mendeklarasikan dukungan navigasi dalam manifes Anda

Aplikasi navigasi Anda harus mendeklarasikan kategori aplikasi mobil androidx.car.app.category.NAVIGATIONdalam filter intent CarAppService:

<application>
    ...
   <service
       ...
        android:name=".MyNavigationCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.NAVIGATION"/>
      </intent-filter>
    </service>
    ...
<application>

Mendukung intent navigasi

Untuk mendukung Intent navigasi ke aplikasi Anda, termasuk intent yang berasal dari Asisten Google menggunakan kueri suara, aplikasi Anda perlu menangani intent CarContext.ACTION_NAVIGATE dalam Session.onCreateScreen dan Session.onNewIntent-nya.

Lihat dokumentasi CarContext.startCarApp untuk detail tentang format intent.

Mengakses template navigasi

Aplikasi navigasi dapat mengakses template berikut yang dirancang khusus untuk aplikasi navigasi. Semua template ini menampilkan permukaan di latar belakang yang dapat diakses oleh aplikasi Anda untuk menggambar peta Anda, beserta informasi lain yang disediakan oleh aplikasi Anda yang bervariasi per template.

  • NavigationTemplate: menampilkan peta bersama dengan pesan informasi opsional atau petunjuk pemilihan rute dan perkiraan perjalanan selama navigasi aktif.
  • PlaceListNavigationTemplate: menampilkan daftar tempat yang dapat digambar dengan penanda yang sesuai di peta.
  • RoutePreviewNavigationTemplate: menampilkan daftar rute yang salah satunya dapat dipilih dan disorot di peta.

Untuk detail selengkapnya tentang cara mendesain antarmuka pengguna aplikasi navigasi menggunakan template tersebut, lihat Panduan Desain Library Aplikasi Android untuk Mobil.

Untuk mendapatkan akses ke template navigasi, aplikasi Anda harus mendeklarasikan izin androidx.car.app.NAVIGATION_TEMPLATES di AndroidManifest.xml:

<uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES"/>

Menggambar Peta

Aplikasi navigasi dapat mengakses Surface untuk menggambar peta pada template yang relevan.

Objek SurfaceContainer kemudian dapat diakses dengan menyetel instance SurfaceCallback ke layanan mobil AppManager:

carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);

SurfaceCallback memberikan callback saat SurfaceContainer tersedia bersama dengan callback lainnya saat properti Surface berubah.

Agar dapat mengakses ke permukaan, aplikasi Anda harus mendeklarasikan izin androidx.car.app.ACCESS_SURFACE dalam AndroidManifest.xml-nya:

<uses-permission android:name="androidx.car.app.ACCESS_SURFACE"/>

Area peta yang terlihat

Host dapat menggambar elemen antarmuka pengguna untuk berbagai template di bagian atas peta. Host akan mengomunikasikan area yang dijamin tidak akan kosong dan sepenuhnya terlihat oleh pengguna dengan memanggil SurfaceCallback.onVisibleAreaChanged. Selain itu, untuk meminimalkan jumlah perubahan, host juga akan memanggil metode SurfaceCallback.onStableAreaChanged dengan kotak terbesar yang akan terlihat berdasarkan template saat ini.

Misalnya, saat aplikasi navigasi menggunakan NavigationTemplate dengan strip tindakan di bagian atas, strip tindakan dapat menyembunyikan dirinya sendiri ketika pengguna tidak berinteraksi dengan layar untuk beberapa saat guna membuat lebih banyak ruang untuk peta. Dalam hal ini, akan ada callback ke onStableAreaChanged dan onVisibleAreaChanged dengan kotak yang sama. Jika strip tindakan disembunyikan, hanya onVisibleAreaChanged yang akan dipanggil dengan area yang lebih besar. Jika pengguna berinteraksi dengan layar, sekali lagi hanya onVisibleAreaChanged yang dipanggil dengan kotak pertama.

Mode gelap

Aplikasi navigasi harus menggambar ulang peta ke instance Surface dengan warna gelap yang sesuai saat host menentukan bahwa kondisi menjaminnya, seperti yang dijelaskan dalam pedoman kualitas aplikasi Android Auto.

Untuk memutuskan apakah Anda harus menggambar peta gelap, Anda dapat menggunakan metode CarContext.isDarkMode. Setiap kali status mode gelap berubah, Anda akan menerima panggilan ke Session.onCarConfigurationChanged.

Aplikasi navigasi harus mengomunikasikan metadata navigasi tambahan dengan host. Host menggunakan informasi untuk menyediakan informasi bagi head unit kendaraan dan untuk mencegah aplikasi navigasi bentrok dengan resource bersama.

Metadata navigasi disediakan melalui layanan mobil NavigationManager yang dapat diakses dari CarContext:

NavigationManager navigationManager = carContext.getCarService(NavigationManager.class);
Memulai, mengakhiri, dan menghentikan navigasi

Agar dapat mengelola beberapa aplikasi navigasi, notifikasi pemilihan rute, dan data cluster kendaraan, host harus mengetahui status navigasi saat ini. Saat pengguna memulai navigasi, aplikasi harus memanggil NavigationManager.navigationStarted. Demikian pula, saat navigasi berakhir, misalnya saat pengguna tiba di tujuan atau pengguna membatalkan navigasi, aplikasi harus memanggil NavigationManager.navigationEnded.

Anda hanya boleh memanggil NavigationManager.navigationEnded saat pengguna selesai menavigasi. Misalnya, jika Anda perlu menghitung ulang rute di tengah perjalanan, gunakan Trip.Builder.setLoading(true) sebagai gantinya.

Terkadang, host memerlukan aplikasi untuk menghentikan navigasi dan memanggil stopNavigation dalam objek NavigationManagerListener yang disediakan oleh aplikasi Anda melalui NavigationManager.setListener. Aplikasi harus berhenti menampilkan informasi belokan berikutnya dalam tampilan cluster, notifikasi navigasi, dan panduan suara.

Informasi perjalanan

Selama navigasi aktif, aplikasi harus memanggil NavigationManager.updateTrip. Informasi yang diberikan dalam panggilan ini akan digunakan di cluster kendaraan dan heads-up display. Tidak semua informasi dapat ditampilkan kepada pengguna bergantung pada kendaraan tertentu yang sedang dikemudikan. Misalnya, Head Unit Desktop menampilkan Step yang ditambahkan ke Trip, tetapi tidak menampilkan informasi Destination.

Untuk menguji apakah informasi tersebut telah menjangkau cluster, alat Head Unit Desktop (DHU) dapat dikonfigurasi untuk menampilkan tampilan cluster sederhana. Buat file cluster.ini dengan konten berikut:

[general]
instrumentcluster = true

Kemudian, Anda dapat memanggil DHU dengan parameter baris perintah tambahan:

dhu -c cluster.ini

Notifikasi belokan demi belokan

Petunjuk navigasi belokan demi belokan (TBT) dapat diberikan dengan notifikasi navigasi yang sering diperbarui. Agar diperlakukan sebagai notifikasi navigasi di layar mobil, builder notifikasi Anda harus melakukan hal berikut:

  1. Tandai notifikasi sebagai sedang berlangsung dengan metode NotificationCompat.Builder.setOngoing.
  2. Tetapkan kategori notifikasi ke Notification.CATEGORY_NAVIGATION.
  3. Perluas notifikasi dengan CarAppExtender.

Notifikasi navigasi akan ditampilkan di widget rel di bagian bawah layar mobil. Jika tingkat kepentingan notifikasi disetel ke IMPORTANCE_HIGH, notifikasi juga akan ditampilkan sebagai notifikasi pendahuluan (HUN). Jika nilai penting tidak ditetapkan dengan metode CarAppExtender.Builder.setImportance, nilai penting saluran notifikasi akan digunakan.

Aplikasi dapat menyetel PendingIntent di CarAppExtender yang akan dikirim ke aplikasi saat pengguna mengetuk HUN atau widget rel.

Jika NotificationCompat.Builder.setOnlyAlertOnce dipanggil dengan nilai true, notifikasi dengan nilai penting yang tinggi akan dikirim hanya sekali di HUN.

Cuplikan berikut ini menunjukkan cara membuat notifikasi navigasi:

new NotificationCompat.Builder(context, myNotificationChannelId)
    ...
    .setOnlyAlertOnce(true)
    .setOngoing(true)
    .setCategory(NotificationCompat.CATEGORY_NAVIGATION)
    .extend(
        new CarAppExtender.Builder()
            .setContentTitle(carScreenTitle)
            ...
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_OPEN_APP.hashCode(),
                    new Intent(ACTION_OPEN_APP)
                        .setComponent(
                            new ComponentName(context, MyNotificationReceiver.class)),
                    0))
            .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
    .build())
Panduan untuk notifikasi belokan demi belokan

Aplikasi navigasi harus memperbarui notifikasi TBT secara teratur tentang perubahan jarak, yang memperbarui widget rel, dan hanya menampilkan notifikasi sebagai HUN. Aplikasi dapat mengontrol perilaku HUN dengan menyetel nilai penting notifikasi dengan metode CarAppExtender.Builder.setImportance. Menetapkan nilai penting ke IMPORTANCE_HIGH akan menampilkan HUN, dan menyetelnya ke nilai lain hanya akan memperbarui widget rel.

Panduan Suara

Untuk memutar panduan navigasi melalui speaker mobil, aplikasi Anda harus meminta fokus audio. Sebagai bagian dari AudioFocusRequest, Anda harus menyetel penggunaan sebagai AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE. Anda juga harus menyetel peningkatan fokus sebagai AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK.

Menyimulasikan navigasi

Untuk memverifikasi fungsi navigasi aplikasi Anda saat mengirimkannya ke Google Play Store, aplikasi Anda harus menerapkan callback NavigationManagerCallback.onAutoDriveEnabled. Saat callback ini dipanggil, aplikasi Anda harus menyimulasikan navigasi ke tujuan yang dipilih saat pengguna memulai navigasi. Aplikasi Anda dapat keluar dari mode ini setiap kali siklus proses Session saat ini mencapai status Lifecycle.Event#ON_DESTROY.

Anda dapat menguji apakah implementasi onAutoDriveEnabled dipanggil dengan menjalankan perintah berikut dari command line:

adb shell dumpsys activity service CAR_APP_SERVICE_NAME AUTO_DRIVE

Contoh:

adb shell dumpsys activity service androidx.car.app.samples.navigation.car.NavigationCarAppService AUTO_DRIVE

Aplikasi mobil navigasi default

Di Android Auto, aplikasi mobil navigasi default sesuai dengan aplikasi navigasi terakhir yang diluncurkan pengguna. Ini adalah aplikasi yang, misalnya, akan menerima intent navigasi saat pengguna memanggil perintah navigasi melalui asisten atau saat aplikasi lain mengirim intent untuk memulai navigasi.

Siklus Proses CarAppService, Sesi, dan Layar

Class Session dan Screen mengimplementasikan antarmuka LifecycleOwner. Saat pengguna berinteraksi dengan aplikasi, callback siklus proses objek Session dan Screen Anda akan dipanggil, seperti yang dijelaskan dalam diagram berikut.

Siklus proses CarAppService dan Sesi

Gambar 1. Siklus proses Session.

Untuk detail selengkapnya, lihat dokumentasi metode Session.getLifecycle.

Siklus proses Layar

Gambar 2. Siklus proses Screen.

Untuk detail selengkapnya, lihat dokumentasi Screen.getLifecycle.

Library Pengujian

Library Pengujian Android untuk Mobil memberikan class tambahan yang dapat Anda gunakan untuk memvalidasi perilaku aplikasi dalam lingkungan pengujian. Misalnya, SessionController memungkinkan Anda melakukan simulasi koneksi ke host dan memastikan Screen dan Template yang tepat telah dibuat dan ditampilkan.

Lihat Contoh untuk contoh penggunaan.

Menjalankan aplikasi di head unit asli

Agar aplikasi Anda berjalan di head unit asli (bukan head unit desktop yang kami sediakan), aplikasi Anda harus didistribusikan melalui Google Play Store. Hal ini memastikan bahwa aplikasi Anda telah diuji dan diperiksa kepatuhannya terhadap pedoman kami. Pedoman ini memastikan aplikasi Anda relevan dengan lingkungan mobil, serta lulus uji gangguan bagi pengemudi kami.

Untuk pengujian selama pengembangan, ada tiga opsi:

  • Menggunakan head unit desktop.
  • Mendorong aplikasi Anda ke internal test track Google Play Store. Jalur pengujian internal memungkinkan Anda menambahkan tim secara manual untuk memungkinkan pengujian internal. Rilis ke jalur ini tidak akan memerlukan peninjauan Play Store.
  • Membagikan aplikasi Anda melalui internal app sharing di Konsol Google Play. Serupa dengan jalur pengujian internal, rilis ke jalur ini tidak memerlukan peninjauan Play Store.

Setiap kali Anda merilis APK ke jalur lain, termasuk jalur tertutup, aplikasi akan menjalani proses peninjauan sebelum disetujui ke jalur tersebut di Play Store. Jika permohonan gagal dalam proses peninjauan, Anda akan menerima informasi tentang alasan mengapa permohonan tidak lulus. Proses ini memungkinkan Anda memperbaiki masalah apa pun untuk mematuhi pedoman kami.

Melaporkan masalah Library Aplikasi Android untuk Mobil

Jika Anda menemukan masalah pada library, laporkan menggunakan Issue Tracker Google. Pastikan untuk mengisi semua informasi yang diminta pada template masalah.

Melaporkan masalah baru

Sebelum mengajukan masalah baru, periksa apakah masalah tersebut sudah tercantum dalam catatan rilis library atau dilaporkan dalam daftar masalah. Anda bisa berlangganan dan memberi suara pada masalah dengan mengklik bintang untuk masalah di tracker. Untuk mengetahui informasi selengkapnya, lihat Berlangganan pada topik Masalah.