Get to know Android Automotive

Mostafa Mazrouh
Qrios
Published in
4 min readMar 23, 2023

Each car manufacturers used to implement its own infotainment system inside its car. Here comes Android Automotive Operating System (AAOS), a new way of standardisation. AAOS runs on the car head independent of user’s mobile. Android Auto on the other hand requires a mobile runs Android. Both of Android Automotive and Android Auto are called Android for cars.

In this article we shall implement an app for Android Automotive to calculate the driving distance of the car. It will look like this:

Let’s get started

In Android studio, go ahead and create a new project, select Automotive, No Activity.

There are 6 categories supported for Android Automotive apps by the time of writing this article you can read all about it here.

Media Service category and Message Service category each of them has a template in Android studio. Other categories don’t, so to make things clear we are building a no activity app to understand the app step by step.

I named the app DistanceMeter, select Jave, and finish.

To install your app on the automotive emulator you need to download the system image and create AVD, follow this link for details. You can choose Volvo or Polestar.

Then to run your app, you need to install Google Automotive App Host, follow my answer on stackoverflow for details.

We need to use Cars App Library to be able to bring our app to the car. Here you can find how it works in details. We will go through its main concepts as we are coding.

  1. The host is the backend component that implements the functionality offered by the library’s APIs so your app can run in the car. The responsibilities of the host range from discovering your app and managing its lifecycle.

2. CarAppService is an abstract service class that your app must implement to be discovered by the host.

Let’s create our own DistanceMeterService that extends CarAppService.

DistanceMeterService is responsible for validating that a host connection can be trusted using createHostValidator() and subsequently providing Session instances for each connection using onCreateSession().

3. A Session serves as the entry point to display information. When the app starts, a session will provide the initial Screen.

Create a new class DistanceMeterScreen extends Screen.

public Template onGetTemplate() {

Row row1 = new Row.Builder()
.setTitle(" ").build();

Row row2 = new Row.Builder()
.setTitle("Hello driver!").build();

Row row3 = new Row.Builder()
.setTitle("Please fasten your seatbelt").build();

Row row4 = new Row.Builder()
.setTitle("Speed limit: 120 km/h").build();

paneBuilder.addRow(row1);
paneBuilder.addRow(row2);
paneBuilder.addRow(row3);
paneBuilder.addRow(row4);

paneBuilder.addAction(
new Action.Builder()
.setTitle("Total distance")
.setOnClickListener(this::onClickTotalDistance)
.build());

return new PaneTemplate.Builder(paneBuilder.build())
.build();
}

Here we create onGetTemplate() method, which returns the Template instance representing the state of the UI to display in the car screen. Here we use PaneTemplate that has a few rows of text and an action button “Total distance” which has a listener method onClickTotalDistance().

When it is clicked, it will show a Toast with driven distance.

private void onClickTotalDistance() {

String distanceMessage = "You drove: ";

if (distanceInMeter < 1000) {
distanceMessage += (int)(distanceInMeter) + " m";
} else {
distanceMessage += (int)(distanceInMeter/1000) + " km";
}

CarToast.makeText(getCarContext(), distanceMessage, CarToast.LENGTH_LONG).show();
}

To get user’s location and therefor calculate the distance, we need to implement onLocationChanged() in LocationListener

@Override
public void onLocationChanged(@NonNull Location location) {

if (startingLocation == null) {
startingLocation = location;
}

currentLocation = location;

distanceInMeter = currentLocation.distanceTo(startingLocation);
}

DistanceMeterScreen uses LocationInteractor to do the calculation and check permissions in the Manifest file

5. For the Manifest file we need to ask permission for location access:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

And we need to export DistanceMeterService to till the Host where to start the app:

<service
android:name="com.example.distancemeter.DistanceMeterService"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService" />
</intent-filter>
</service>

5. Last thing we need to do in the project to run is to add car app library to the dependences in build.gradle file:

dependencies {

implementation 'androidx.appcompat:appcompat:1.6.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

implementation "androidx.car.app:app-automotive:1.3.0-rc01"
}

Now the project is ready, choose Volvo or Polestar emulator and run.

If the emulator didn’t ask for location permission, you need to do it yourself.

In the emulator go to the settings -> applications -> show all apps -> your app -> permissions -> Allow while using app.

Now if you click Total distance button in the app you should see a message: “You drove 0 m”.

To simulate location change of the car, go to the three dots of the emulator -> location -> choose another coordinates -> Set location.

Wait a few moments for the change to take effect and then click Total distance button again. You should see that you drove some meters or kilometres.

You can find the source code on my github: https://github.com/MostafaMazrouh/DistanceMeter

--

--

Mostafa Mazrouh
Qrios
Editor for

Mobile architect — write about iOS, Android and Automotive