Android Auto

July 30, 2026 · View on GitHub

Verified against androidx.car.app 1.7.0, July 2026.

The constraint you need to know about first

Android Auto does not have an app category that fits a checklist app, and that is not an oversight you can work around. The host will only surface an app whose CarAppService declares one of a fixed set of categories — navigation, parking, charging, POI, IOT, weather, messaging, calling, media. Google reviews the declared category against what the app actually does before it can ship to Android Auto users through the Play Store.

This app declares androidx.car.app.category.POI in AndroidManifest.xml purely so the host will load it at all. That declaration is not defensible in a Play Store review and the app is not submitted to one. The Android Auto surface here is for sideloading with developer mode enabled, on your own head unit.

The phone app has no such restriction and is the primary way to use this.

Enabling it on your own device

  1. Install the APK on the phone.
  2. Open the Android Auto settings (Settings → Connected devices → Android Auto, or the standalone app on older versions).
  3. Tap the Version entry ten times to unlock developer mode.
  4. Overflow menu → Developer settings → enable Unknown sources.
  5. Reconnect to the head unit. "Driving Checklists" appears in the app launcher.

If it does not appear, the usual causes are: developer mode not actually enabled, the phone app never launched once after install (the disclaimer gate has to be cleared), or a head unit that filters by category more aggressively than the phone does.

Testing without a car

The Desktop Head Unit ships with the Android SDK:

# once
sdkmanager "extras;google;auto"

# each session
adb forward tcp:5277 tcp:5277
$ANDROID_HOME/extras/google/auto/desktop-head-unit

Enable Start head unit server in Android Auto developer settings first. The app must be a debuggable build for HostValidator.ALLOW_ALL_HOSTS_VALIDATOR to apply — a release build talks only to hosts on the library's allowlist, which the desktop head unit is not on. Use ./gradlew installDebug for head-unit work.

Row limits and why every screen pages

The host caps how many rows a list template may contain. Six is the common figure, and it is queried at runtime rather than assumed:

carContext.getCarService(ConstraintManager::class.java)
    .getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_LIST)

A full checklist runs to thirty-odd items, so every car screen in this app pages instead of truncating — see CarPaging.kt. One row per page is reserved for the More link, so the page size stays constant and an item does not shift between pages as the limit changes.

Two consequences worth remembering when editing the car screens:

  • Section headers are not used in the car. A sectioned list spends the same row budget on headers as on content. The section name is folded into each row's second line instead.
  • A Row may carry a toggle or a click listener, not both. Checklist rows carry toggles, so the "More" row is a separate browsable row rather than a toggle row.

Shared state

Both surfaces read and write the same DataStore through ChecklistRepository, which is a process-wide singleton. The car screens collect the repository flows in init and call invalidate() on each emission, so a box ticked on the phone redraws on the head unit without any explicit cross-process plumbing — the CarAppService runs in the same process as the activity.