> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/ja/navigation/llms.txt)

# Get Started with Android Auto

This guide shows you how to configure **Android Auto** features in a Android app using the **Mapbox Navigation SDK for Android**.

## Prerequisites

Before you begin, make sure you have:

-   Completed the [Navigation SDK installation guide](https://docs.mapbox.com/android/ja/navigation/guides/install/) and have a working Navigation SDK app building and running on your Android device
-   Reviewed the [Google developer documentation](https://developer.android.com/training/cars/apps) for developing Android Auto apps
-   Reviewed Google's [functionality checklist](https://developer.android.com/docs/quality-guidelines/car-app-quality#functionality) to make sure your app meets Google Play requirements

> **Note**
> 
> If you want to use Mapbox Maps in Android Auto without the Navigation SDK, refer to the [Mapbox Android Auto Extension](https://github.com/mapbox/mapbox-maps-android/tree/main/extension-androidauto).

## Configure Android Auto Support

### Step 1: Add Android Auto dependencies

Add the *Android Auto components* module to your app-level `build.gradle` file. The library version matches the Navigation SDK version, ensuring compatibility:

**Groovy**

Title: `build.gradle`

```groovy
dependencies {
  ...
    implementation "com.mapbox.navigationcore:android-ndk27:3.28.2"
    implementation "com.mapbox.navigationcore:android-auto-components-ndk27:3.28.2"
    // if your app does not require 16 KB page size support, the default dependency without -ndk27 can be used
    // implementation "com.mapbox.navigationcore:android-auto-components:3.28.2"
  ...
}
```

**Kotlin**

Title: `build.gradle.kts`

```kotlin
dependencies {
  ...
    implementation("com.mapbox.navigationcore:android-ndk27:3.28.2")
    implementation("com.mapbox.navigationcore:android-auto-components-ndk27:3.28.2")
    // if your app does not require 16 KB page size support, the default dependency without -ndk27 can be used
    // implementation("com.mapbox.navigationcore:android-auto-components:3.28.2")
  ...
}
```

### Step 2: Declare Android Auto support in your manifest

Add the required elements to the `<application>` tag in your `AndroidManifest.xml`:

1.  Add the 3 required permissions to gain access to the user's location and allow the app to continue running even when the user navigates away from the app.
2.  Add metadata to declare support for Android Auto.
3.  Create a `CarAppService` with the appropriate intent filter to label this app as a navigation application.

```xml
<application>
    ...

    <!-- Required permissions -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

    ...
    
    <!-- Metadata for Android Auto support -->
    <meta-data
        android:name="com.google.android.gms.car.application"
        android:resource="@xml/automotive_app_desc" />

    <!-- CarAppService for navigation -->
    <service
        android:name=".car.MainCarAppService"
        android:exported="true"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:foregroundServiceType="location">

        <intent-filter>
            <action android:name="androidx.car.app.CarAppService" />
            <category android:name="androidx.car.app.category.NAVIGATION" />
        </intent-filter>
    </service>
    
    ...
</application>
```

> **Note: Important**
> 
> The `automotive_app_desc` resource is included by the Mapbox Navigation Android Auto SDK, so you don't need to create it yourself. Make sure to specify the correct category (`androidx.car.app.category.NAVIGATION`) or your app will be rejected by Google Play.

## Implement `CarAppService` and Session

### Step 1: Create your `CarAppService`

Create a `CarAppService` class that serves as the entry point for Android Auto:

```kotlin
class MainCarAppService : CarAppService() {
    override fun createHostValidator() = HostValidator.ALLOW_ALL_HOSTS_VALIDATOR

    override fun onCreateSession() = MainCarSession()
}
```

### Step 2: Implement your Session

The `Session` is a `LifecycleOwner` and the main component for managing your Android Auto experience. Create a `MainCarSession` class that sets up the map, navigation, and screens. This example creates the `FREE_DRIVE` screen if location permission is granted, or the `NEEDS_LOCATION_PERMISSION` screen otherwise.

```kotlin
package com.example.cleanandroidproject.car

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import androidx.annotation.RequiresPermission
import androidx.car.app.Screen
import androidx.car.app.Session
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import com.mapbox.maps.MapInitOptions
import com.mapbox.maps.extension.androidauto.MapboxCarMap
import com.mapbox.navigation.ui.androidauto.map.MapboxCarMapLoader
import com.mapbox.navigation.base.options.NavigationOptions
import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp
import com.mapbox.navigation.ui.androidauto.MapboxCarContext
import com.mapbox.navigation.ui.androidauto.deeplink.GeoDeeplinkNavigateAction
import com.mapbox.navigation.ui.androidauto.screenmanager.MapboxScreen
import com.mapbox.navigation.ui.androidauto.screenmanager.MapboxScreenManager
import com.mapbox.navigation.ui.androidauto.screenmanager.prepareScreens
import com.mapbox.navigation.core.lifecycle.MapboxNavigationObserver
import com.mapbox.navigation.core.MapboxNavigation

/**
 * MainCarSession manages the lifecycle of your Android Auto app.
 * This is the entry point for your app when it runs in Android Auto.
 */
class MainCarSession : Session() {

    // MapboxCarMapLoader handles loading and rendering of the map in Android Auto
    private val carMapLoader = MapboxCarMapLoader()
    
    // MapboxCarMap provides the map surface for Android Auto
    private val mapboxCarMap = MapboxCarMap().registerObserver(carMapLoader)
    
    // MapboxCarContext integrates Mapbox Navigation with Android Auto lifecycle
    private val mapboxCarContext = MapboxCarContext(lifecycle, mapboxCarMap)

    // Navigation observer handles starting/stopping trip sessions when attached/detached
    private val navigationObserver = object : MapboxNavigationObserver {
        @RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
        override fun onAttached(mapboxNavigation: MapboxNavigation) {
            // Start the trip session to begin receiving location updates
            mapboxNavigation.startTripSession()
        }

        override fun onDetached(mapboxNavigation: MapboxNavigation) {
            // Stop the trip session when detached to save battery
            mapboxNavigation.stopTripSession()
        }
    }

    init {
        // Prepare the screen navigation graph for Android Auto
        mapboxCarContext.prepareScreens()

        lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onCreate(owner: LifecycleOwner) {
                // Initialize MapboxNavigationApp if not already setup
                if (!MapboxNavigationApp.isSetup()) {
                    MapboxNavigationApp.setup(
                        NavigationOptions.Builder(carContext)
                            .build()
                    )
                }

                // Attach the car lifecycle to MapboxNavigationApp
                // This ensures navigation state is managed with the car session
                MapboxNavigationApp.attach(owner)

                // Register the navigation observer to handle trip session lifecycle
                MapboxNavigationApp.registerObserver(navigationObserver)

                // Setup the MapboxCarMap with SHARED context mode
                // SHARED context is required when using Android Auto widgets
                mapboxCarMap.setup(
                    carContext,
                    MapInitOptions(
                        context = carContext,
                        mapOptions = com.mapbox.maps.MapOptions.Builder()
                            .contextMode(com.mapbox.maps.ContextMode.SHARED)
                            .build()
                    )
                )
            }

            override fun onDestroy(owner: LifecycleOwner) {
                // Clean up: unregister observer and detach from navigation
                MapboxNavigationApp.unregisterObserver(navigationObserver)
                MapboxNavigationApp.detach(owner)
                mapboxCarMap.clearObservers()
            }
        })
    }

    /**
     * Create the initial screen based on location permission status.
     * Returns either the FREE_DRIVE screen or a permission request screen.
     */
    override fun onCreateScreen(intent: Intent): Screen {
        // Check if location permission is granted
        val firstScreenKey = if (isLocationPermissionGranted()) {
            // If permission granted, show the Free Drive navigation screen
            MapboxScreenManager.current()?.key ?: MapboxScreen.FREE_DRIVE
        } else {
            // If permission not granted, show permission request screen
            MapboxScreen.NEEDS_LOCATION_PERMISSION
        }

        // Create and return the screen using MapboxScreenManager
        return mapboxCarContext.mapboxScreenManager.createScreen(firstScreenKey)
    }

    /**
     * Handle new intents, including geo deeplinks for navigation.
     * This enables voice-activated navigation ("Navigate to...")
     */
    @OptIn(com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI::class)
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        // Handle geo deeplinks (e.g., geo:latitude,longitude)
        GeoDeeplinkNavigateAction(mapboxCarContext).onNewIntent(intent)
    }

    /**
     * Helper function to check if location permission is granted.
     */
    private fun isLocationPermissionGranted(): Boolean {
        return carContext.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) ==
                PackageManager.PERMISSION_GRANTED
    }
}
```

The session code above handles `MapboxNavigation` on its own and assumes you are not using it elsewhere in your app. You can use the following minimal `MainActivity.kt` code to test this session (the android app must still request location permissions on the mobile device):

```kotlin
package com.example.cleanandroidproject

import android.Manifest
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            var hasPermission by remember { mutableStateOf(false) }
            
            val launcher = rememberLauncherForActivityResult(
                ActivityResultContracts.RequestMultiplePermissions()
            ) { hasPermission = it.values.any { granted -> granted } }

            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                if (hasPermission) {
                    Text("Permission granted!")
                } else {
                    Button(onClick = {
                        launcher.launch(arrayOf(
                            Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION
                        ))
                    }) {
                        Text("Grant Location Permission")
                    }
                }
            }
        }
    }
}
```

If you are using `MapboxNavigation` in your mobile app, refer to the [Manage State Between Car and App](#manage-state) section below.

Once this app is installed on your device, connect it to Android Auto to see your navigation app, accept location permissions, and you will see the free drive map showing your current location.

![A Android Auto screenshot of the free drive screen.](https://docs.mapbox.com/android/ja/assets/ideal-img/navigation-androidauto-freedrive.03d60c8.480.png)

## Manage State Between Car and App

The Android Auto extension integrates with the [Jetpack Lifecycle Library](https://developer.android.com/topic/libraries/architecture/lifecycle), allowing you to share navigation state between your mobile app and car display.

### Use `MapboxNavigationApp` for shared state

The `MapboxNavigationApp` singleton manages the lifecycle of `MapboxNavigation` across your app and Android Auto session. This ensures:

-   Navigation state persists when switching between phone and car displays
-   Resources are properly managed and shared
-   Location updates and route progress continue seamlessly

```kotlin
// In your mobile app Activity
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // Set up MapboxNavigationApp once
        if (!MapboxNavigationApp.isSetup()) {
            MapboxNavigationApp.setup(
                NavigationOptions.Builder(this)
                    .accessToken(getString(R.string.mapbox_access_token))
                    .build()
            )
        }
        
        // Attach to the activity lifecycle
        MapboxNavigationApp.attach(this)
    }
}
```

The same `MapboxNavigationApp` instance is automatically used in your `MainCarSession`, ensuring seamless state management.

For more details, see the [Initialize the SDK](https://docs.mapbox.com/android/ja/navigation/guides/initialization/#1-set-up-mapboxnavigationapp) guide and [Android Auto Lifecycle documentation](https://developer.android.com/training/cars/apps#carappservice-session-screen-lifecycles).

## Customize Your Experience

The Android Auto components library provides default screens and experiences for common navigation scenarios. You can use these as-is or customize them for your specific needs.

### Available default screens

The library includes pre-built screens for:

-   [**Free Drive**](https://docs.mapbox.com/android/ja/navigation/guides/androidauto/free-drive): Map view without active navigation
-   [**Route Preview**](https://docs.mapbox.com/android/ja/navigation/guides/androidauto/route-preview): Show the route before starting navigation
-   [**Active Guidance**](https://docs.mapbox.com/android/ja/navigation/guides/androidauto/active-guidance): Turn-by-turn guidance with map
-   **Arrival**: Destination arrival screen
-   [**Location Permission**](https://docs.mapbox.com/android/ja/navigation/guides/androidauto/location-permission): Request location access from the mobile device

### Customization options

You can customize the car experience in several ways:

1.  **Custom screens**: Extend or replace default screens using the `MapboxScreenManager`
2.  **Map styling**: Customize map appearance through `MapboxCarMapLoader`
3.  **Navigation options**: Configure routing preferences, maneuver instructions, and more
4.  **UI components**: Adjust colors, fonts, and layout through Android Auto templates

Refer to the [Mapbox Android Auto Extension](https://github.com/mapbox/mapbox-maps-android/tree/main/extension-androidauto) for additional map customization examples.

## Troubleshooting

Details

**App not appearing in Android Auto**

If your app doesn't show up in Android Auto:

-   Verify that the `meta-data` and `CarAppService` are correctly declared in your `AndroidManifest.xml`
-   Check that the `category` in your intent filter matches your app type (`androidx.car.app.category.NAVIGATION`)
-   Make sure your `minSdk` is 23 or higher
-   Try disconnecting and reconnecting your device to Android Auto

Details

**Location permissions not working**

Android Auto apps must request location permissions from the mobile device:

-   Location permissions cannot be requested directly from the car display
-   Use the `MapboxScreen.NEEDS_LOCATION_PERMISSION` screen to prompt users to grant permissions on their phone
-   Make sure your mobile app properly requests and handles location permissions

Details

**Navigation state not syncing between phone and car**

If navigation state isn't syncing:

-   Verify that you're using `MapboxNavigationApp.attach()` in both your mobile Activity and `CarSession`
-   Make sure `MapboxNavigationApp.setup()` is called before attaching to any lifecycle
-   Check that you're not creating multiple `MapboxNavigation` instances manually