Добавляем поддержку Android Auto в существующее приложение

Введение

Как запустить Desktop Head Unit (DHU) для Android Auto: пошаговая инструкция

Автомобильные интерфейсы становятся неотъемлемой частью повседневной жизни. Всё больше пользователей ожидают, что любимые приложения будут доступны не только на телефоне, но и на экране автомобиля. Для разработчика добавление поддержки Android Auto открывает не только новую аудиторию, но и возможность выделиться среди кандидатов на рынке труда. Проекты, связанные с автомобильными платформами, демонстрируют понимание современных трендов, умение работать со специфическими ограничениями и заботу о пользовательском опыте в условиях, где безопасность стоит на первом месте.

В этой статье мы покажем, как за один рабочий день добавить поддержку Android Auto в уже готовое приложение. Вы познакомитесь с Car App Library, научитесь создавать автомобильный сервис и адаптировать существующий код под экраны машин. Всё это мы протестируем на эмуляторе DHU, который уже обсуждали в предыдущей статье «Как запустить DHU для Android Auto». После прочтения вы сможете добавить полученный результат в портфолио и уверенно рассказать о нём на собеседовании.

Что потребуется:

  • готовое Android-приложение (например, простой трекер поездок или список задач);
  • базовые знания архитектуры приложений (ViewModel, репозитории);
  • установленный эмулятор DHU (если ещё нет - воспользуйтесь нашей инструкцией).

Никаких специальных знаний об автомобильной разработке не нужно - мы разберём всё по шагам.

Минимальные изменения для поддержки Android Auto

Чтобы приложение стало доступно в автомобиле, не нужно переписывать его целиком. Google предоставляет Car App Library - набор инструментов, который берёт на себя всю работу по взаимодействию с автомобильным хостом. Нам остаётся лишь создать автомобильный сервис, описать стартовый экран и добавить несколько зависимостей.

Добавление зависимостей

Откройте файл build.gradle вашего модуля (обычно app) и добавьте две библиотеки:

dependencies {
    implementation 'androidx.car.app:app:1.2.0'
    implementation 'androidx.car.app:app-projected:1.2.0'
}

Версия 1.2.0 - стабильная на момент написания статьи. Если вы используете более новую, проверьте актуальность в официальной документации. После синхронизации проект будет готов к автомобильным экспериментам.

Создание автомобильного сервиса

В Android Auto взаимодействие с приложением происходит через специальный сервис, наследующий CarAppService. Он управляет жизненным циклом сессии и предоставляет объект Session, который, в свою очередь, создаёт экраны.

Создайте новый класс, например MyCarAppService, со следующим содержимым:

import android.content.Intent
import androidx.car.app.CarAppService
import androidx.car.app.Session
import androidx.car.app.Screen
import androidx.car.app.CarContext

class MyCarAppService : CarAppService() {

    override fun onCreateSession(): Session {
        // Возвращаем объект Session, который будет управлять экранами
        return object : Session() {
            override fun onCreateScreen(intent: Intent): Screen {
                // При запуске автомобильного приложения показываем наш главный экран
                return MainScreen(carContext)
            }
        }
    }
}

Пока MainScreen ещё не существует - мы создадим его чуть позже. Важно понимать: сервис создаётся один раз и живёт всё время, пока приложение активно в автомобиле.

Обновление манифеста

Как любой сервис, его нужно объявить в AndroidManifest.xml. Кроме того, необходимо добавить разрешение на работу с поверхностью автомобиля (она нужна для отрисовки) и указать категорию приложения (например, навигация или простое приложение).

Добавьте следующие строки внутрь тега <manifest> (обратите внимание: разрешение должно быть на уровне манифеста, а не внутри <application>):

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />

    <application>
        <service
            android:name=".MyCarAppService"
            android:exported="true">
            <intent-filter>
                <action android:name="androidx.car.app.CarAppService" />
                <category android:name="androidx.car.app.category.NAVIGATION" />
            </intent-filter>
        </service>
        <!-- остальные компоненты приложения -->
    </application>
</manifest>

Категория NAVIGATION подходит для приложений, которые помогают водителю ориентироваться. Если ваше приложение относится к другому типу (музыка, новости, подкасты), выберите соответствующую категорию. Полный список можно найти в документации.

Теперь автомобильная система сможет обнаружить наше приложение.

Создание базового экрана

Самое время создать простой экран, который увидит водитель. В Car App Library все экраны строятся на основе шаблонов (Template). Самый универсальный - ListTemplate, который отображает список элементов.

Создайте класс MainScreen:

import androidx.car.app.CarContext
import androidx.car.app.Screen
import androidx.car.app.model.*

class MainScreen(carContext: CarContext) : Screen(carContext) {

    override fun onGetTemplate(): Template {
        // Строим одну строку с приветствием
        val row = Row.Builder()
            .setTitle("Добро пожаловать!")
            .addText("Это автомобильная версия приложения")
            .build()

        // Добавляем её в список (используем addRow)
        val list = ItemList.Builder()
            .addRow(row)
            .build()

        // Оборачиваем список в шаблон
        return ListTemplate.Builder()
            .setTitle("Главное меню")
            .setSingleList(list)
            .build()
    }
}

Этот экран покажет одну строку с текстом. Позже мы наполним его реальными данными из вашего приложения.

Интеграция с существующим проектом (на примере трекера поездок)

Теперь, когда основа готова, нужно связать автомобильный модуль с основной логикой приложения. Главная задача - не дублировать код, а использовать уже существующие репозитории, ViewModel и другие компоненты.

Разделение UI для телефона и автомобиля

Самый чистый способ - вынести автомобильные экраны в отдельный модуль (например, :car), а общую бизнес-логику оставить в основном модуле или в модуле :core. Если ваш проект небольшой, можно оставить всё в одном модуле, но чётко разделить пакеты: ui.phone и ui.car. Так вы избежите случайного использования недоступных в автомобиле виджетов.

Для доступа к данным создайте интерфейс репозитория или use case, который будет общим для обеих версий. Например, для трекера поездок:

// Общий интерфейс в модуле :core
interface TripRepository {
    fun getRecentTrips(limit: Int): List<Trip>
    fun getTripById(id: String): Trip?
}

Реализация остаётся в основном модуле, а автомобильный модуль получает её через внедрение зависимостей (Hilt, Dagger или ручное DI).

Адаптация существующих функций на примере списка поездок

Автомобильный интерфейс накладывает строгие ограничения: не более шести элементов в списке, минимум текста, обязательные иконки. Вам придётся переосмыслить, как показывать данные. Например, если в телефоне вы выводите подробную таблицу поездок, в машине уместны только последние три с крупными кнопками.

Вот как можно адаптировать экран списка поездок для автомобиля:

class TripsScreen(carContext: CarContext, private val repository: TripRepository) : Screen(carContext) {

    override fun onGetTemplate(): Template {
        val trips = repository.getRecentTrips(5) // берём не больше 5
        val listBuilder = ItemList.Builder()

        trips.forEach { trip ->
            val row = Row.Builder()
                .setTitle(trip.destination)
                .addText(trip.distance)
                .setOnClickListener { // открыть детали поездки
                    val screenManager = carContext.getCarService(ScreenManager::class.java)
                    screenManager.push(TripDetailScreen(carContext, trip.id))
                }
                .build()
            listBuilder.addRow(row)
        }

        return ListTemplate.Builder()
            .setTitle("Последние поездки")
            .setSingleList(listBuilder.build())
            .build()
    }
}

Обратите внимание на setOnClickListener - все действия в автомобиле должны быть большими и легко нажимаемыми. Для навигации между экранами используем ScreenManager, полученный через carContext.getCarService().

Обработка ошибок и обновление состояния

В реальном приложении данные могут загружаться асинхронно, а сеть - отсутствовать. Для автомобиля нужно показывать понятные сообщения об ошибках и, возможно, кнопку повтора. Используйте MessageTemplate:

fun showError(message: String, onRetry: () -> Unit): Template {
    val action = Action.Builder()
        .setTitle("Повторить")
        .setOnClickListener { onRetry() }
        .build()
    return MessageTemplate.Builder(message)
        .addAction(action)
        .build()
}

Если данные обновляются (например, при изменении в репозитории), автомобильный экран должен реагировать. В Screen можно подписаться на Flow с помощью carContext.lifecycleScope:

class TripsScreen(carContext: CarContext, repository: TripRepository) : Screen(carContext) {

    init {
        carContext.lifecycleScope.launch {
            repository.tripsFlow.collect {
                // При получении новых данных перерисовываем экран
                invalidate()
            }
        }
    }
    // ... остальной код
}

Метод invalidate() вызывает повторный onGetTemplate, обновляя интерфейс.

Тестирование через эмулятор

Перед тем как запускать приложение на реальной машине, удобно использовать эмулятор DHU (Desktop Head Unit). Мы уже рассказывали, как его установить и настроить, в статье «Как запустить DHU для Android Auto». Запустите эмулятор, подключите к нему ваше приложение через Android Studio и проверьте, как выглядят экраны. Убедитесь, что все кнопки работают, нет вылетов и интерфейс не перегружен.

Для отладки можно использовать логи - Log.d будет виден в консоли Android Studio. Обратите особое внимание на работу с разрешениями: автомобильные приложения требуют ACCESS_SURFACE и другие права, которые могут быть не запрошены в телефоне.

Лучшие практики для автомобильных приложений

Разработка под Android Auto сильно отличается от обычной мобильной. Вот несколько рекомендаций, которые помогут сделать приложение удобным и безопасным.

Дизайн под большие экраны и расстояние

Водитель смотрит на экран с расстояния вытянутой руки и часто на ходу. Элементы управления должны быть крупными, контрастными и хорошо читаться даже при ярком солнечном свете. Избегайте мелких кнопок и тонких шрифтов. Car App Library автоматически подстраивает размеры, но вы можете влиять на них с помощью стилей.

Минимизация отвлечения водителя

Система Android Auto автоматически блокирует сложные операции во время движения (например, ввод длинного текста). Тем не менее, разработчик тоже должен заботиться о безопасности: не показывать видео, не требовать скролла длинных списков, отключать ненужные уведомления. Всё, что может отвлечь водителя дольше чем на секунду, должно быть упрощено или убрано.

Голосовое управление

Голос - основной способ взаимодействия за рулём. Полноценная поддержка голоса требует интеграции с Google Assistant или создания собственного VoiceInteractionService. Для простых приложений можно ограничиться встроенными возможностями: в Car App Library элементы списка автоматически получают голосовые метки (content description). Этого достаточно для базовой навигации. Если вы хотите реализовать сложные голосовые сценарии, обратитесь к документации Google.

Как добавить этот проект в портфолио

Поддержка Android Auto - отличный кейс для портфолио. Он показывает, что вы умеете работать с современными платформами, учитываете контекст использования и соблюдаете требования безопасности.

Почему это ценят работодатели
Автомобильные приложения требуют понимания ограничений (размер экрана, ввод, безопасность) и умения адаптировать существующий код под новые условия. Это выделяет вас среди разработчиков, которые пишут только под телефоны. К тому же интеграция с Android Auto - это работа с проприетарными API Google, что тоже плюс.

Как описать этот проект в резюме
Добавьте в раздел «Опыт» или «Pet-проекты» строчку:

«Добавил поддержку Android Auto в существующее приложение-трекер поездок: создал автомобильный сервис, адаптировал UI под ограничения экрана в машине, организовал передачу данных через общий репозиторий, протестировал на эмуляторе DHU. Использовал Car App Library, Kotlin, архитектуру на основе ViewModel и репозиториев.»

Если проект был реальным и выложен на GitHub, обязательно укажите ссылку. Работодатель сможет зайти, посмотреть код и убедиться в качестве.

Подробнее об оформлении портфолио читайте в нашей статье «Как собрать первое портфолио мобильного Android-разработчика».

Заключение и следующие шаги

Мы рассмотрели, как за один рабочий день добавить поддержку Android Auto в готовое приложение. Вы узнали, как создать автомобильный сервис, объявить его в манифесте, построить первый экран и протестировать всё на эмуляторе DHU. Теперь ваше приложение может работать не только на телефоне, но и в автомобиле, а вы получили ценный опыт для портфолио.

Что изучить дальше

  • Расширенные возможности Car App Library - навигация, медиа-шаблоны, работа с картами.
  • Публикация приложения для Android Auto - требования Google Play, процесс верификации.
    Важно: для публикации в официальном каталоге требуется верификация через программу Android for Cars. Без одобрения от Google приложение не будет доступно в магазине, даже если оно работает в эмуляторе.
  • Тестирование на реальном устройстве - если у вас есть машина с поддержкой Android Auto, обязательно попробуйте.

Задание для закрепления материала:
Добавьте второй экран в своё автомобильное приложение - например, детальный просмотр выбранного элемента. Используйте для передачи данных между экранами ScreenManager. Это поможет вам лучше понять навигацию в Car App Library.

Удачной разработки и безопасных дорог!


Новости [1] [2] [3]... Android/ iOS/ J2ME[1] [2] [3])/ Android/ Архив/ Карьера

Яндекс.Метрика
MobiLab.ru © 2005-2026
При использовании материалов сайта ссылка на www.mobilab.ru обязательна