Меню

andipanda.dev

CaRadio: как я адаптировал сенсорное управление CarPlay

В предыдущей статье я рассказал, как экспериментировал с FastCarPlay и LIVI, а затем доработал процедуру инициализации Carlinkit, чтобы добиться стабильного подключения телефона.

Но успешное подключение CarPlay — это только часть задачи. Чтобы пользоваться системой в автомобиле, нужно ещё и удобное управление.

В моём случае основным устройством ввода был сенсорный экран. И именно с его поддержкой пришлось разбираться на следующем этапе разработки.

Первые эксперименты с сенсорным управлением

FastCarPlay уже имел поддержку сенсорного ввода. Однако в первоначальном виде проект был в значительной степени ориентирован на управление с клавиатуры.

Для разработки и проверки работы CarPlay это вполне подходящий вариант. Но мне хотелось получить полноценную автомобильную магнитолу, которой можно пользоваться непосредственно через экран, без клавиатуры и мыши.

Во время первых экспериментов я столкнулся с нестабильной работой сенсорного управления на своём оборудовании.

Насколько помню, после нескольких касаний или попытки выполнить свайп CarPlay переставал реагировать на прикосновения. При этом само приложение продолжало работать.

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

Поэтому делать выводы о причинах неисправности в оригинальном проекте было бы неправильно.

К тому же я всё равно собирался создавать собственный интерфейс магнитолы, а значит, обработку управления рано или поздно пришлось бы адаптировать под CaRadio.

От клавиатуры к сенсорному экрану

FastCarPlay использовал SDL — библиотеку, с которой я начал знакомиться после возвращения к проекту.

Одно из её преимуществ заключается в том, что она позволяет получать события от разных устройств ввода и обрабатывать их непосредственно в приложении.

Для моей магнитолы это было удобно.

Я мог использовать мышь во время разработки на компьютере, а на Raspberry Pi работать с сенсорным экраном. При этом основная логика управления могла оставаться общей.

Но для CarPlay недостаточно просто определить, что пользователь прикоснулся к дисплею.

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

Все эти действия необходимо преобразовать в команды, понятные системе CarPlay.

Нажатия, перемещения и свайпы

Сенсорное управление состоит не только из одиночных нажатий.

Например, чтобы открыть приложение, достаточно коснуться соответствующего значка. А чтобы прокрутить список или переместиться по карте, уже требуется обработка движения пальца.

Поэтому в CaRadio я предусмотрел обработку нескольких типов событий: начало касания, перемещение и отпускание пальца.

В случае обычного нажатия приложение получает координаты точки, в которой пользователь коснулся экрана, и передаёт соответствующее событие дальше.

При перемещении пальца необходимо передавать изменение координат, чтобы CarPlay мог реагировать на жест.

Когда палец отрывается от дисплея, отправляется событие завершения касания.

На первый взгляд всё довольно просто. Но для корректной работы важно учитывать последовательность этих событий и не смешивать их с управлением собственным интерфейсом магнитолы.

Отдельно я сохранил возможность использовать мышь. Это полезно во время разработки и проверки приложения без подключённого сенсорного дисплея.

Координаты экрана и CarPlay

Ещё одна задача — правильно передавать координаты касаний.

Дисплей магнитолы имеет собственное разрешение, а изображение CarPlay обрабатывается в своей системе координат.

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

Поэтому в CaRadio координаты пересчитываются с учётом размеров окна приложения и масштаба изображения CarPlay.

Это позволяет отделить физическое разрешение дисплея от координат, которые используются для управления.

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

Как вернуться из CarPlay в CaRadio

Когда CarPlay занимает весь экран, возникает ещё один вопрос: как вернуться в собственный интерфейс магнитолы?

Можно было бы использовать отдельную физическую кнопку. Но мне хотелось, чтобы основные действия были доступны непосредственно с сенсорного экрана.

Поэтому я предусмотрел специальную область в левом верхнем углу дисплея.

Когда пользователь касается этой области, событие обрабатывается самой CaRadio и не передаётся в CarPlay как обычное нажатие.

После этого можно открыть главный экран магнитолы и получить доступ к другим функциям приложения.

При этом остальная часть экрана продолжает использоваться для управления CarPlay.

Таким образом, одно и то же устройство ввода обслуживает две разные задачи: управление телефоном через CarPlay и управление самой магнитолой.

Почему я решил сделать это самостоятельно

Моя цель не заключалась в том, чтобы полностью переписать управление FastCarPlay или доказать, что исходная реализация была неправильной.

Мне требовалось решение, которое соответствовало бы конкретной конструкции CaRadio.

Я хотел самостоятельно контролировать обработку событий, понимать, куда передаётся каждое касание, и иметь возможность добавлять собственные элементы управления.

Кроме того, такой подход хорошо соответствует моему общему принципу разработки: по возможности использовать простые и понятные решения без лишних программных слоёв.

Конечно, самостоятельная реализация тоже требует времени на отладку.

Но в результате я получил управление, которое можно развивать вместе с остальными функциями магнитолы, не ограничиваясь возможностями первоначального интерфейса.

Несколько слов о FastCarPlay

Здесь хочу отдельно поблагодарить автора FastCarPlay.

Именно благодаря его работе мне удалось вернуться к идее собственной магнитолы с CarPlay и довести её до результата, которым я пользуюсь в автомобиле.

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

Поэтому описанные изменения — не попытка сделать FastCarPlay «правильнее» или «лучше». Я лишь адаптировал существующую реализацию под собственное оборудование и задачи.

Открытые проекты ценны именно тем, что позволяют не начинать каждый раз с нуля, а изучать готовые решения и развивать их в собственном направлении.

Что в итоге

В результате сенсорное управление стало частью CaRadio, а не просто дополнительной возможностью для взаимодействия с CarPlay.

Теперь приложение может обрабатывать нажатия и перемещения пальца, преобразовывать координаты под изображение CarPlay и отделять управление телефоном от управления самой магнитолой.

Для меня это был ещё один шаг от экспериментального запуска CarPlay на Raspberry Pi к системе, которой действительно удобно пользоваться в автомобиле.

Но изображение и управление — только часть мультимедийной системы.

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

Об этом расскажу в следующей статье.