В прошлой серии мы научились вытаскивать из машины данные. Мы знаем скорость, обороты двигателя и даже какая дверь открыта. Руки чешутся вывести всё это на огромный экран в 4K, добавить анимаций, графиков и запустить YouTube на фоне, да?

Не спешите.

Если вы сделаете это, ваше приложение никогда не попадет в стор. А если вы работаете на OEM (автопроизводителя) и протащите это в прод — вас, возможно, проклянут водители, въехавшие в столб, пока разглядывали ваш красивый график расхода топлива.

Сегодня говорим о Driver Distraction — главной боли и главной фишке разработки под авто. О том, как сделать интерфейс, который не убивает.

Почему всё так плохо (или хорошо?)

В мобильной разработке мы боремся за Engagement (вовлеченность). Мы хотим, чтобы юзер залипал в экран часами. В Automotive мы боремся за Glanceability (быстрое считывание).

Есть золотое правило, написанное кровью (и регуляторами типа NHTSA):

Правило 2 секунд: Водитель должен считать информацию и вернуться взглядом на дорогу менее чем за 2 секунды. Всё, что дольше — потенциальная авария на вашей совести.

Поэтому Android Automotive OS (AAOS) — это самый строгий надзиратель, которого вы встречали. В системе есть специальный механизм — UX Restrictions Engine. Он работает постоянно и бьёт приложение по рукам, если машина начала движение.

Как система понимает, что пора «закручивать гайки»?

В Android есть системный сервис CarUxRestrictionsManager. Он мониторит состояние автомобиля (Gear, Speed, Parking Brake) и меняет состояние ограничений.

Как только вы переключаете коробку передач в Drive или скорость превышает 0 км/ч, система переходит в режим Distraction Optimized (DO).

Что происходит в этот момент:

  1. Текст режется: Длинные списки обрезаются (обычно до 6 элементов).

  2. Ввод блокируется: Никаких клавиатур. Хочешь найти песню? Голосовой ввод или выбор из избранного.

  3. Видео гаснет: YouTube, игры и браузеры блокируются на уровне системы (или показывают заглушку).

Кодим безопасность

Давайте посмотрим, как ваше приложение узнает, что «вечеринка закончилась» и пора прятать сложные меню.

Если вы пишете на чистом Android (не используя Car App Library, о ней ниже), вам придется обрабатывать это руками.

import android.car.Car
import android.car.drivingstate.CarUxRestrictions
import android.car.drivingstate.CarUxRestrictionsManager

// Получаем менеджер (по аналогии с PropertyManager из прошлой статьи)
val carUxRestrictionsManager = car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE) 
    as CarUxRestrictionsManager

// Слушатель изменений
val listener = object : CarUxRestrictionsManager.OnUxRestrictionsChangedListener {
    override fun onUxRestrictionsChanged(restrictionInfo: CarUxRestrictions) {
        handleRestrictions(restrictionInfo)
    }
}

// Регистрация
carUxRestrictionsManager.registerListener(listener)

fun handleRestrictions(restrictions: CarUxRestrictions) {
    val isDistractionOptimized = restrictions.isRequiresDistractionOptimization()
    
    if (isDistractionOptimized) {
        // МАШИНА ЕДЕТ!
        // 1. Скрываем клавиатуру
        // 2. Убираем сложные настройки
        // 3. Упрощаем UI, оставляем только огромные кнопки
        videoView.visibility = View.GONE
        warningTextView.visibility = View.VISIBLE
    } else {
        // МАШИНА СТОИТ (Parked)
        // Можно показать клавиатуру, видео и настройки
        videoView.visibility = View.VISIBLE
        warningTextView.visibility = View.GONE
    }
}

Нюанс для профи (Active vs Background)

Ограничения могут зависеть не только от скорости, но и от типа контента. Например, для навигации правила чуть мягче, чем для настройки эквалайзера. Но общее правило: если машина едет — интерфейс должен быть тупым, как пробка.

Дизайн для толстых пальцев и плохих дорог

Даже если вы обработали программные ограничения, остаётся UX. Вы когда-нибудь пробовали попасть в кнопку размером 24dp на экране телефона, который трясется на "лежачем полицейском"?

Google выкатил гайдлайны, которые делают больно дизайнерам, привыкшим к мобилкам:

  • Touch Target: Минимум 76x76 dp. Да, кнопки должны быть огромными.

  • Текст: Минимум 24sp для основного текста. Забудьте про мелкие сноски.

  • Контраст: Не просто хороший, а идеальный. Солнце бликует, очки у водителя темные — он должен видеть интерфейс боковым зрением.

  • Иерархия: Не больше 3-4 кликов до любой функции. Если чтобы включить подогрев сиденья, надо зайти в Меню -> Настройки -> Климат -> Сиденья — вы плохой человек.

Чит-код: Car App Library

Если всё вышеперечисленное звучит как "слишком много геморроя", то у Google есть решение — Car App Library (CAL).

Это библиотека, где вы вообще не рисуете UI в XML или Jetpack Compose. Вы отдаете системе данные (текст, иконку, список), а система сама рисует интерфейс по безопасным шаблонам.

Плюсы:

  • Вы автоматически проходите проверки на Distraction Guidelines.

  • Система сама блокирует списки при движении.

  • Интерфейс выглядит нативно в любой машине (хоть Volvo, хоть Honda).

Минусы:

  • Шаг влево, шаг вправо — расстрел. Вы не можете подвинуть кнопку на 5 пикселей или поменять шрифт. Вы заложник шаблонов.

Для медиа-приложений (Spotify, Radio) и навигации CAL — это стандарт де-факто. Но если вы делаете что-то для управления "железом" (как мы обсуждали в прошлой статье), вам придется страдать и рисовать Custom UI с учетом всех ограничений вручную.

Итого

Разработка под Automotive — это постоянный баланс между "хочу сделать красиво" и "не хочу, чтобы водитель отвлекся".

  1. Safety First: Ваше приложение не должно убивать.

  2. Слушайте CarUxRestrictionsManager: Это ваш главный друг и враг.

  3. Крупнее, проще, контрастнее: Дизайн должен быть "дубовым".

В следующий раз мы соберем всё вместе: возьмем данные из VHAL (скорость), наложим ограничения UX (если едем быстро) и попробуем собрать реальное демо-приложение.

Не переключайтесь, и смотрите на дорогу!