Creating an App in Android Automotive OS

Sehrish Shoaib
TribalScale
Published in
6 min readMay 25, 2022

Written by: Sebastian Valencia & Sehrish Shoaib, Agile Software Engineering, TribalScale

📫 Subscribe to receive our content here.

💬 Have any questions about our Android Automotive capabilities? Click here to chat with one of our experts!

In the previous article we gave a general overview of Android Automotive, also referred to as AAOS in the current domain of Android. Since this a new domain for Android, we have many upcoming and changing features being supported in terms of development and design principles.

Users can download apps directly from the Google Play Store on the infotainment system in their car, they no longer have to connect their phones. Instead they will be viewing apps on an interface that is specifically designed for their car screen. This is what makes AAOS apps so convenient and useful in terms of usability and availability.

In this article we will explore how to create a general app on AAOS.

Getting Started

AAOS emulator system images that currently can be used for AAOS app development are listed below, these will change based on the OEM (Original Equipment Manufacturer). To add these emulators to your project follow the steps given here.

  1. Generic System Image
  2. Polestar 2 System Image
  3. Volvo System Image

CarAppService, Session and Templates

The development of Android apps for AAOS differs from the mobile Android app development due to some restrictions on the UI side. Let’s explore these requirements below while we develop an app on AAOS.

All necessary settings and modifications required in the Android Manifest.xml are given in here.

Each AAOS car app is defined by the following app architecture consisting of a CarAppService, a session and one or more screens.

Components of Host application on AAOS

The CarAppService validates that a host connection can be trusted and henceforth be used to provide session instances.

Create the following file:

class CarHomeService : CarAppService() {override fun onCreateSession(): Session {
return CarHomeSession()
}
override fun createHostValidator(): HostValidator {
return if(applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE !=0){
HostValidator.ALLOW_ALL_HOSTS_VALIDATOR
}
else{
HostValidator.Builder(applicationContext)
.addAllowedHosts(androidx.car.app.R.array.hosts_allowlist_sample)
.build()
}
}
}

A session serves as the entry point for an app to display the initial screen on the app launch. A session has a lifecycle and can be considered similar to an activity in mobile Android development.

Create the following file:

class CarHomeSession : Session() {override fun onCreateScreen(intent: Intent): Screen {
return CarHomeScreen(carContext)
}
}

To use the AAOS app within your car, the next step is too add a file named automotive_app_desc.xml as shown below:

Adding file automotive_app_desc.xml

Within this file we will add the following lines of code:

<?xml version=”1.0" encoding=”utf-8"?>
<automotiveApp>
<uses name=”template” />
</automotiveApp>

The screen of an AAOS app will display the user interface via the given templates. The generic templates that can be used include:

  • List or Grid
  • Pane
  • Message or Long Message
  • Search
  • Sign-in

Home Screen

After creating the Service and Session files above, we’ll be creating a Home screen for our app using a Grid template and then a Pane template to show further information to the user once they click on a grid element.

Below we are defining CarHomeScreen using a Grid template. As you can see, the return type must be Screen otherwise we will get errors.

Then we define the function onGetTemplate() so that we can use the predefined Grid template given by the Android Car App library.

class CarHomeScreen(carContext: CarContext):Screen(carContext) {  override fun onGetTemplate(): Template {

In the Grid template we can create clickable icons. We’ll use IconCompat.createWithResource to define all the required icons.

// Icon for Car
val mGridIcon = IconCompat.createWithResource(
carContext,R.drawable.ic_car_icon)
// Icon for Alerts
val mGridAlertIcon = IconCompat.createWithResource(
carContext,R.drawable.ic_alert_icon)
// Icon for Search
val mGridSearchIcon = IconCompat.createWithResource(
carContext,R.drawable.ic_search_icon)

In order to define the grid items we can first initialize them separately using GridItem.Builder() which will need the following attributes:

  • setTitle("Place title here")
  • setImage
  • setOnclickListener
//Grid Item no.1
val gridItemCar = GridItem.Builder()
.setTitle(“Car Info”)
.setImage(CarIcon.Builder(mGridIcon).build(),
GridItem.IMAGE_TYPE_LARGE)
.setOnClickListener {
screenManager.push(CarInfoScreen(carContext))
}.build()
//Grid Item no.2
val gridItemAlerts = GridItem.Builder()
.setTitle(“Alerts”)
.setImage(CarIcon.Builder(mGridAlertIcon).build(),
GridItem.IMAGE_TYPE_LARGE)
.setOnClickListener {
screenManager.push(AlertsScreen(carContext))
}.build()
//Grid Item no. 3
val gridItemSearch = GridItem.Builder()
.setTitle(“Search”)
.setImage(CarIcon.Builder(mGridLocationIcon).build(),
GridItem.IMAGE_TYPE_LARGE)
.setOnClickListener {
screenManager.push(SearchScreen(carContext))
}.build()

Within the click listener we have used the ScreenManager class that allows apps to include a different number of screens with the option of using different templates. In this class we can stack screens in the order which a user is clicking them and then pop them using the back button or provide user navigation as required by the app.

Combine all the grid items into a list using ItemList.Builder() as shown below. We can add more grid items, however due to screen interface dimensions there is a grid limit based on the car as to how many can be shown to the user.

val gridList = ItemList.Builder()
.addItem(gridItemCar)
.addItem(gridItemAlerts)
.addItem(gridItemSearch)
.build()

At last we can now return the template to the getTemplate function we called so that it can be rendered on screen.

return GridTemplate.Builder()
.setTitle(“Car Information App”)
.setSingleList(gridList)
.build()
}
}

This is what it will look like in the emulator:

Home Screen in Generic Automotive Emulator

Alerts Screen

To define the Alerts screen from the Home screen menu, we can use the Pane template and add more rows as required by our app. In this screen we are also setting a back action in the Header Action so that we can navigate back to our Home screen.

class AlertsScreen(carContext: CarContext): Screen(carContext) {override fun onGetTemplate(): Template {  val row = Row.Builder().setTitle(“Alerts”).build()  val pane = Pane.Builder()
.addRow(row)
.build()
return PaneTemplate.Builder(pane)
.setHeaderAction(Action.BACK)
.build()
}
}

AAOS Emulator — Extended Controls

The emulators provided for Android Automotive have Extended Controls that also allow us to see how your app will work in the parked state as well as driving state. As we can see below currently the car is in a parked state with the Parking brake on and the Car speed at 0 mph.

Extended Controls for Emulator — Parked State

We can change this setting to Driving by toggling the Parking brake off and changing the Gear to D (Drive) with an increased Car speed of 45 mph.

Extended Controls for Emulator — Driving State

As a result the app will be paused and the following screen will be displayed showing that we cannot interact or view this app while we are in a driving state.

Automotive Emulator When Car is in a Driving State

Final Thoughts

Google has also provided extensive car sample apps to learn from which include all the various templates that can be used with the Android Car App library. The GitHub repository for these samples can be viewed here.

AAOS has given Android developers the opportunity to use their skills in the automotive domain. This is a very exciting prospect that can enhance the Android user’s experience, as well as broaden the outreach for those developing these apps.

Check out the next two parts of this blog series where we:

Sebastian Valencia and Sehrish Shoaib are Agile Software Engineers at TribalScale who have been working together on Android Automotive development projects. They have been researching and implementing the latest Android Car App library and have made a lot of progress in this new domain.

TribalScale is a global innovation firm that helps enterprises adapt and thrive in the digital era. We transform teams and processes, build best-in-class digital products, and create disruptive startups. Learn more about us on our website. Connect with us on Twitter, LinkedIn & Facebook!

--

--

Sehrish Shoaib
TribalScale

Sehrish is an Android Engineer who is passionate about learning new technologies in the Android world.