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
- Install the APK on the phone.
- Open the Android Auto settings (Settings → Connected devices → Android Auto, or the standalone app on older versions).
- Tap the Version entry ten times to unlock developer mode.
- Overflow menu → Developer settings → enable Unknown sources.
- 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
Rowmay 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.