$30 off During Our Annual Pro Sale. View Details »

Going on a road trip with Android Auto

cmota
April 27, 2023

Going on a road trip with Android Auto

Android is truly everywhere. It's running on the phone, watch, TV, car, and there are even some fridges and toasters that want to be part of the family. While they're still under development, Android Auto is starting to gain a lot of adoption.

In this talk, we're going to travel around the road of Android Auto, see its use cases and go through its functionalities, so you can later implement them on your app. All of this without moving your desk to be inside a car.

Jump in, it's going to be an amazing journey.

cmota

April 27, 2023
Tweet

More Decks by cmota

Other Decks in Technology

Transcript

  1. android auto
    @cafonsomota
    Going on a road trip with

    View Slide

  2. bonjour!
    @cafonsomota

    View Slide

  3. @cafonsomota
    👨💻 Android GDE


    🧙 Android/ KMP cra
    ft
    sman (and advocate)


    ✍ Author @kodecodev


    🗺 Loves travel, photography and running


    🇫🇷 Je suis ravie d'être ici à Android Makers

    View Slide

  4. @cafonsomota
    resources
    linktr.ee/cafonsomota

    View Slide

  5. android
    @cafonsomota

    View Slide

  6. powered device?
    Who has an
    android
    @cafonsomota

    View Slide

  7. android everywhere
    @cafonsomota

    View Slide

  8. android everywhere
    @cafonsomota

    View Slide

  9. android everywhere
    @cafonsomota

    View Slide

  10. android for cars
    @cafonsomota

    View Slide

  11. @cafonsomota
    By avg. people spend
    ~600
    per year on cars
    hours
    Source: bristolstreet.co.uk/news/drivers-in-england-spend-25-days-per-year-in-their-cars

    View Slide

  12. @cafonsomota
    By avg. people spend
    25 days
    per year on cars
    Source: bristolstreet.co.uk/news/drivers-in-england-spend-25-days-per-year-in-their-cars

    View Slide

  13. What do you do while
    commuting?
    @cafonsomota

    View Slide

  14. Dance
    Think about life
    Listen to music Nothing Listen podcasts
    Endless radio advertisements
    Making phone calls
    Record a podcast Look for radars
    Listen to audio books
    Football matches
    Talk to the person in the car
    Sleep
    Switch between radio stations
    Plan my day
    Nothing
    Sing Eat

    View Slide

  15. Source: Distracted driving in Europe by Diana Sure, Head of NGO on Responsible Driving in Europe
    drivers
    36%
    read text/emails
    while driving

    View Slide

  16. Source: Distracted driving in Europe by Diana Sure, Head of NGO on Responsible Driving in Europe
    10-30% of road collisions
    in Europe are due to the use
    of smartphones while driving

    View Slide

  17. … people have even changed. From using a
    mobile now for texting. What they’re
    actually doing now is surfing the net.
    They’re looking at their Instagram portfolio,
    their Facebook.

    - David Sheahan, Garda National Roads Policing Bureau, Ireland
    Source: Distracted driving in Europe by Diana Sure, Head of NGO on Responsible Driving in Europe

    View Slide

  18. can we solve this?
    How
    @cafonsomota

    View Slide

  19. android for cars
    The Belfry of …
    Eiffel Tower
    Orly
    @cafonsomota
    Android Auto Android Automotive Assistant Driving Mode

    View Slide

  20. Suppo
    rt
    is added via mobile .apk/.aab
    android for cars
    android auto
    Projection of your device, optimized for vehicles
    Requires your sma
    rt
    phone to be connected
    Runs with the same look and feel on all cars
    The Belfry of …
    Eiffel Tower
    Orly

    View Slide

  21. @cafonsomota
    android for cars
    android automotive OS (AAOS)
    Requires a separate .apk/.aab
    OS for cars
    App is installed into your car
    Adapted to OEM colors and styling

    View Slide

  22. @cafonsomota
    android for cars
    assistant driving mode
    Requires Google Maps
    Set of features available when driving
    Voice commands to read/send messages, make calls, etc.
    Not available on all countries

    View Slide

  23. android for cars
    @cafonsomota
    why?
    Limit user distraction
    Voice enabled commands
    Quick access to actions
    More enjoyable (and safe) ride

    View Slide

  24. android auto
    @cafonsomota

    View Slide

  25. @cafonsomota
    cars with Android Auto
    100+ Million

    View Slide

  26. android auto
    apps in production
    @cafonsomota

    View Slide

  27. android auto
    apps in production
    Confetti app
    github.com/joreilly/Confe
    tt
    i/androidApp/…/auto
    @cafonsomota

    View Slide

  28. android auto
    @cafonsomota
    why?
    Empower drivers with your app
    Easy to implement
    New market that you can reach

    View Slide

  29. android auto car library
    @cafonsomota

    View Slide

  30. android auto
    car library
    @cafonsomota
    Vehicle-optimized templates for UI
    Handle user input
    Responsive screen sizing

    View Slide

  31. car library
    for android auto and automotive
    build.gradle.kts
    implementation("androidx.car.app:app:1.4.0-alpha01")

    View Slide

  32. android auto
    overview
    @cafonsomota

    View Slide

  33. android auto
    overview
    @cafonsomota
    meta-data
    AndroidManifest

    View Slide

  34. car library
    for android auto and automotive
    AndroidManifest


    android:name="com.google.android.gms.car.application"


    android:resource="@xml/automotive_app"


    tools:ignore="MetadataTagInsideApplicationTag"
    />

    View Slide

  35. car library
    for android auto and automotive
    AndroidManifest






    />


    automotiveApp>

    View Slide

  36. car library
    for android auto and automotive
    AndroidManifest


    android:name="androidx.car.app.theme"


    android:resource="@style/Night.Theme.Confetti"


    tools:ignore="MetadataTagInsideApplicationTag"
    />

    View Slide

  37. car library
    for android auto and automotive
    AndroidManifest


    android:name="androidx.car.app.minCarApiLevel"


    android:value="1"


    tools:ignore="MetadataTagInsideApplicationTag"
    />

    View Slide

  38. car library
    for android auto and automotive
    AndroidManifest


    android:name="androidx.car.app.minCarApiLevel"


    android:value="1"


    tools:ignore="MetadataTagInsideApplicationTag"
    />

    Latest API: 6

    View Slide

  39. app categories
    for android auto and automotive
    @cafonsomota

    View Slide

  40. app categories
    for android auto and automotive
    @cafonsomota
    Audio players, radio, audiobooks,…
    Media (audio)
    Read messages aloud, reply via voice input,…
    Messaging
    Provide turn-by-turn directions
    Navigation
    Android auto only

    View Slide

  41. app categories
    for android auto and automotive
    @cafonsomota
    Monitor and control the state of home devices
    Internet of Things (IOT)
    Stream videos while the car is parked
    Video apps
    Android Automotive only (for now)
    Navigate to POI’s, parking, charging,…
    Point of Interest (POI)

    View Slide

  42. android auto
    overview
    @cafonsomota
    CarAppService

    View Slide

  43. app categories
    for android auto and automotive
    AndroidManifest


    android:name=".auto.ConfettiCarAppService"


    android:exported="true">





    /
    >

    />

    < /
    intent-filter>



    service>


    View Slide

  44. app categories
    for android auto and automotive
    AndroidManifest


    android:name=".auto.ConfettiCarAppService"


    android:exported="true">





    /
    >

    />

    < /
    intent-filter>



    service>


    View Slide

  45. app categories
    for android auto and automotive
    AndroidManifest


    android:name=".auto.ConfettiCarAppService"


    android:exported="true">





    /
    >

    />

    < /
    intent-filter>



    service>


    View Slide

  46. app categories
    for android auto and automotive
    AndroidManifest


    android:name=".auto.ConfettiCarAppService"


    android:exported="true">





    /
    >

    />

    < /
    intent-filter>



    service>


    ⚠ POI and IOT needs to be uppercase
    (otherwise your app will get rejected, trust me 😅)

    View Slide

  47. android auto
    overview
    @cafonsomota
    CarAppService
    createHostValidator

    View Slide

  48. android auto
    overview
    @cafonsomota
    onCreateSession
    CarAppService

    View Slide

  49. android auto
    overview
    @cafonsomota
    onCreateSession
    CarAppService
    onCreateScreen

    View Slide

  50. android auto
    overview
    @cafonsomota
    onCreateSession
    CarAppService
    onGetTemplate
    ConferencesScreen
    onCreateScreen

    View Slide

  51. app categories
    for android auto and automotive
    AndroidManifest
    class ConfettiCarAppService: CarAppService() {


    override fun createHostValidator(): HostValidator {


    return HostValidator.Builder(applicationContext)


    .addAllowedHosts(R.array.hosts_allowlist)


    .build()


    }


    override fun onCreateSession(sessionInfo: SessionInfo) {


    return object : Session() {


    override fun onCreateScreen(intent: Intent) =


    ConferencesScreen(carContext)





    View Slide

  52. app categories
    for android auto and automotive
    AndroidManifest
    class ConfettiCarAppService: CarAppService() {


    override fun createHostValidator(): HostValidator {


    return HostValidator.Builder(applicationContext)


    .addAllowedHosts(R.array.hosts_allowlist)


    .build()


    }


    override fun onCreateSession(sessionInfo: SessionInfo) {


    return object : Session() {


    override fun onCreateScreen(intent: Intent) =


    ConferencesScreen(carContext)





    View Slide

  53. app categories
    for android auto and automotive
    AndroidManifest
    class ConfettiCarAppService: CarAppService() {


    override fun createHostValidator(): HostValidator {


    return HostValidator.Builder(applicationContext)


    .addAllowedHosts(R.array.hosts_allowlist)


    .build()


    }


    override fun onCreateSession(sessionInfo: SessionInfo) {


    return object : Session() {


    override fun onCreateScreen(intent: Intent) =


    ConferencesScreen(carContext)





    View Slide

  54. android auto templates
    @cafonsomota

    View Slide

  55. overview
    @cafonsomota
    Designed for driving
    Strict implementation rules
    Shows impo
    rt
    ant information glanceable
    Discourages distraction
    car templates

    View Slide

  56. ListTemplate


    GridTemplate


    SignInTemplate


    MessageTemplate


    LongMessageTemplate


    SearchTemplate


    PaneTemplate
    overview
    for android auto and automotive for POI and IOT apps
    TabTemplate


    PlaceListTemplate
    for navigation apps
    PlaceListTemplate


    MapTemplate


    RoutePreviewTemplate


    NavigationTemplate
    car templates
    ⚠ API level 6
    ⚠ Parked only*
    ⚠ Parked only*
    * requires user a
    tt
    ention/interaction

    View Slide

  57. ListTemplate
    App name
    List item one
    List item two
    List item three
    List item four
    @cafonsomota
    car templates

    View Slide

  58. ListTemplate
    @cafonsomota
    car templates

    View Slide

  59. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    ListTemplate
    car templates

    View Slide

  60. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    ListTemplate
    car templates

    View Slide

  61. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    ListTemplate
    car templates

    View Slide

  62. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    ListTemplate
    car templates

    View Slide

  63. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    ListTemplate
    car templates

    View Slide

  64. car templates
    ListTemplate
    var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota

    View Slide

  65. Section One
    Title One
    Text one
    Section Two
    Title two
    Text two
    Category
    @cafonsomota
    car templates
    ListTemplate with SectionedItemList

    View Slide

  66. @cafonsomota
    ListTemplate with SectionedItemList
    car templates

    View Slide

  67. var listBuilder =aItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {a


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    car templates
    ListTemplate with SectionedItemList

    View Slide

  68. var listBuilder =aItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    val listTemplate = ListTemplate.Builder()


    listTemplate.addSectionedList(


    SectionedItemList.create(


    listBuilder.build(),


    startTime))


    return listTemplate.apply {a


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    ListTemplate with SectionedItemList
    car templates

    View Slide

  69. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    val listTemplate = ListTemplate.Builder()


    listTemplate.addSectionedList(


    SectionedItemList.create(


    listBuilder.build(),


    startTime))


    return listTemplate.apply {


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    car templates
    ListTemplate with SectionedItemList

    View Slide

  70. Category
    Text one Text two Text three
    Text four Text
    fi
    ve Text six
    @cafonsomota
    car templates
    GridTemplate

    View Slide

  71. @cafonsomota
    car templates
    GridTemplate

    View Slide

  72. var listBuilder =aItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {a


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    car templates
    ListTemplate

    View Slide

  73. var listBuilder =aItemList.Builder()


    listBuilder.addItem(


    Row.Builder()


    .setTitle(conference.name)


    .build())


    return ListTemplate.Builder().apply {a


    setTitle("Confetti")


    setHeaderAction(Action.APP_ICON)


    setSingleList(listBuilder.build())


    }.build()


    @cafonsomota
    car templates
    ListTemplate

    View Slide

  74. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    GridItem.Builder()


    .setTitle(speaker.name)


    .setText(speaker.company)


    .setImage(image).build())


    return GridTemplate.Builder().apply {


    setTitle("Speakers")


    setHeaderAction(Action.BACK)


    setSingleList(listBuilder.build())


    }.build()
    @cafonsomota
    car templates
    GridTemplate

    View Slide

  75. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    GridItem.Builder()


    .setTitle(speaker.name)


    .setText(speaker.company)


    .setImage(image).build())


    return GridTemplate.Builder().apply {


    setTitle("Speakers")


    setHeaderAction(Action.BACK)


    setSingleList(listBuilder.build())


    }.build()
    @cafonsomota
    car templates
    GridTemplate

    View Slide

  76. var listBuilder = ItemList.Builder()


    listBuilder.addItem(


    GridItem.Builder()


    .setTitle(speaker.name)


    .setText(speaker.company)


    .setImage(image).build())


    return GridTemplate.Builder().apply {


    setTitle("Speakers")


    setHeaderAction(Action.BACK)


    setSingleList(listBuilder.build())


    }.build()
    @cafonsomota
    car templates
    GridTemplate

    View Slide

  77. app templates
    restrictions
    @cafonsomota
    Some templates have mandatory prope
    rt
    ies
    There’s a limit of 5 templates that can be pushed during the
    fl
    ow of a task
    There’s a maximum number of items per template

    View Slide

  78. What if there’s
    @cafonsomota
    no template
    for my use case?

    View Slide

  79. app templates
    what if there’s no template for my use case?
    @cafonsomota
    You can make a request for it on Google’s issue tracker
    Or…

    View Slide

  80. 🤫
    @cafonsomota

    View Slide

  81. car templates
    what if there’s no template for my use case?
    @cafonsomota
    Draw directly in the su
    rf
    ace canvas once it’s available
    Create and set a Su
    rf
    aceCallback
    You can use NavigationTemplate for this

    View Slide

  82. car templates
    what if there’s no template for my use case?
    val surfaceCallback = object : SurfaceCallback {


    override fun onSurfaceAvailable(container: SurfaceContainer) {


    val canvas: Canvas? = container.surface
    ?.
    lockCanvas(null)




    //
    Do all calculations


    canvas
    ?.
    drawBitmap(bitmap, width, height, Paint())


    container.surface
    ?.
    unlockCanvasAndPost(canvas)


    }


    }


    View Slide

  83. car templates
    what if there’s no template for my use case?
    val surfaceCallback = object : SurfaceCallback {


    override fun onSurfaceAvailable(container: SurfaceContainer) {


    val canvas: Canvas? = container.surface
    ?.
    lockCanvas(null)




    //
    Do all calculations


    canvas
    ?.
    drawBitmap(bitmap, width, height, Paint())


    container.surface
    ?.
    unlockCanvasAndPost(canvas)


    }


    }


    View Slide

  84. car templates
    what if there’s no template for my use case?
    val surfaceCallback = object : SurfaceCallback {


    override fun onSurfaceAvailable(container: SurfaceContainer) {


    val canvas: Canvas? = container.surface
    ?.
    lockCanvas(null)




    //
    Do all calculations


    canvas
    ?.
    drawBitmap(bitmap, width, height, Paint())


    container.surface
    ?.
    unlockCanvasAndPost(canvas)


    }


    }


    View Slide

  85. car templates
    what if there’s no template for my use case?
    val surfaceCallback = object : SurfaceCallback {


    override fun onSurfaceAvailable(container: SurfaceContainer) {


    val canvas: Canvas? = container.surface
    ?.
    lockCanvas(null)




    //
    Do all calculations


    canvas
    ?.
    drawBitmap(bitmap, width, height, Paint())


    container.surface
    ?.
    unlockCanvasAndPost(canvas)


    }


    }


    View Slide

  86. car templates
    override fun onGetTemplate(): Template {


    carContext.getCarService(AppManager
    ::
    class.java)


    .setSurfaceCallback(surfaceCallback)


    return NavigationTemplate.Builder()


    .setActionStrip(ActionStrip.Builder()


    .addAction(


    Action.Builder()


    .setTitle("Close")


    .build())


    .build()).build()


    }


    what if there’s no template for my use case?

    View Slide

  87. car templates
    override fun onGetTemplate(): Template {


    carContext.getCarService(AppManager
    ::
    class.java)


    .setSurfaceCallback(surfaceCallback)


    return NavigationTemplate.Builder()


    .setActionStrip(ActionStrip.Builder()


    .addAction(


    Action.Builder()


    .setTitle("Close")


    .build())


    .build()).build()


    }


    what if there’s no template for my use case?

    View Slide

  88. car templates
    override fun onGetTemplate(): Template {


    carContext.getCarService(AppManager
    ::
    class.java)


    .setSurfaceCallback(surfaceCallback)


    return NavigationTemplate.Builder()


    .setActionStrip(ActionStrip.Builder()


    .addAction(


    Action.Builder()


    .setTitle("Close")


    .build())


    .build()).build()


    }


    what if there’s no template for my use case?

    View Slide

  89. app templates
    what if there’s no template for my use case?
    @cafonsomota
    Close

    View Slide

  90. Your car app is going to be
    reviewed. You need to follow
    Google’s design guidelines
    for vehicles.
    developers.google.com/cars/design

    View Slide

  91. android auto how to run?
    @cafonsomota

    View Slide

  92. android auto
    how to run?
    Desktop Head Unit (DHU)
    Simulator


    Can install any (debug) app


    Not connected to the car


    Needs to connect to the phone
    The Belfry of …
    Eiffel Tower
    Orl
    @cafonsomota

    View Slide

  93. android auto
    how to run?
    Desktop Head Unit (DHU) Car Head Unit (DHU)
    Physical device


    Requires an app from store


    Not connected to the car


    Needs to connect to the phone
    Simulator


    Can install any (debug) app


    Not connected to the car


    Needs to connect to the phone
    The Belfry of …
    Eiffel Tower
    Orl
    @cafonsomota

    View Slide

  94. android auto
    how to run?
    Desktop Head Unit (DHU) Car Head Unit (DHU) Cars with Android Auto
    Physical device


    Requires an app from store


    Connected to the car


    Needs to connect to the phone
    Physical device


    Requires an app from store


    Not connected to the car


    Needs to connect to the phone
    Simulator


    Can install any (debug) app


    Not connected to the car


    Needs to connect to the phone
    The Belfry of …
    Eiffel Tower
    Orl

    View Slide

  95. android auto lessons learned
    @cafonsomota

    View Slide

  96. android auto
    lessons learned
    @cafonsomota
    There’s no suppo
    rt
    to load ImageVector, for instance. You’ll need to use drawables
    Templates aren’t Composable
    You can request it, or try to create your own
    Some templates might be missing for your use cases
    You’ll need to handle this, and call invalidate() a
    ft
    erwards to refresh the screen
    There’s no direct solution to fetch an image
    TabTemplate only exists on CarAppApiLevel 6 (for now)
    Not all templates are backward po
    rt
    able

    View Slide

  97. android auto
    lessons learned
    @cafonsomota
    You’ll need to use keep in proguard
    Minify and R8 removes car app classes
    Especially the ones under androidx GitHub repo
    See and run the car samples
    There are mandatory elements that you need to set and rules to follow
    Read the documentation

    View Slide

  98. android auto key takeaways
    @cafonsomota

    View Slide

  99. android auto
    key takeaways
    @cafonsomota
    Less is more, only show information that can be easily glanced and accessed
    Simplicity is key
    Not the other way around
    Your app needs to adapt to the car
    Keep touch/key actions to a minimum
    Voice input actions
    Keep task
    fl
    ows sho
    r
    Provide sho
    rt
    cuts and show recurrent actions
    fi
    rst

    View Slide

  100. resources
    linktr.ee/cafonsomota
    @cafonsomota

    View Slide