Відтворення аудіо в авто: як завести Android Auto
Привіт! Мене звати Петро Білий, я Android Engineer в EdTech-компанії Headway. Займаюся розробкою вже досить давно — ще з часів, коли доводилося підтримувати 14 API з допомогою бібліотек сумісності. Сьогодні розповім, що таке Android Auto, про способи інтеграції аудіо через ваш застосунок та надам корисні поради, які хотів би почути сам, коли починав. Також поділюся особливостями реалізації, налаштування інтерфейсу і стилів елементів та розв’язання технічних проблем.
Що таке Android Auto
Android Auto — це система, яка транслює інформацію з телефону на екран автомобіля та відображає спрощений інтерфейс, щоби водій не відволікався під час кермування. З’явилася у 2015 році й швидко набула популярності, а до 2018 вже була інтегрована в автомобілях більшості виробників. На початку працювала з Pixel і Samsung, а потім і на пристроях інших виробників.
Як це працює: телефон підключається до автомобіля — через кабель або бездротове зʼєднання — і через спеціальний застосунок (зазвичай попередньо встановлений) передає зображення на екран автомобіля. У цій системі автомобіль виступає просто як екран, тоді як телефон обробляє команди користувача та виконує всі дії.
Як створити застосунок для Android Auto
Є декілька способів інтегрувати Android Auto, серед яких — розробка повноцінного застосунку. Проте слід врахувати, що оскільки всім керує телефон, ви пишете не застосунок у класичному розумінні, а модуль як розширення до наявного застосунку. Під час водіння використання медіа може відволікати водія і бути небезпечним. Тому Google висуває суворі вимоги до роботи застосунків в автомобілі, яких досить складно дотриматися.
Простішим рішенням є реалізація MediaBrowser — способу передачі даних з вашого застосунку на інші програми або сервіси, зокрема на Android Auto. Його легко інтегрувати, якщо у вашому застосунку вже є фонове відтворення аудіо. Якщо ж аудіо відтворюється точково на одному екрані, може знадобитися деяке доопрацювання.
Android Auto надає готовий уніфікований інтерфейс від Google, який відповідає всім вимогам для безпечного використання під час водіння. Вимог від Google не так багато, і основні з них досить прості. Тож, фактично, ви просто створюєте базову інтеграцію для передавання медіаконтенту, і система автоматично забезпечує його сумісність з Android Auto. Ваш застосунок може передавати дані на Android Auto і взаємодіяти з ним за допомогою невеликих підказок типу «показати цей елемент» або «запустити той елемент», але про це — далі.
Реалізація MediaBrowser в Android має декілька підходів. Розглянемо кожен із них, щоб зрозуміти їхні переваги та недоліки:
MediaBrowserService — нативний варіант, доступний в кожній версії Android. Однак якщо обрати цей шлях, доведеться вручну підтримувати всі оновлення кожної нової версії Android. Також він вимагає значних додаткових зусиль, як-от створення власного плеєра та налаштування сумісності, тому цей підхід вважається застарілим і менш ефективним.
MediaBrowserServiceCompat — бібліотека, створена для покращення MediaBrowserService та усунення певних обмежень оригінального сервісу. Хоча вона досить непогано працювала, наразі Google не підтримує її та рекомендує перехід на MediaLibraryService. Також підключення через MediaBrowserServiceCompat часто вимагає ручної обробки певних елементів, наприклад, завантаження іконок для нотифікацій.
MediaLibraryService — офіційний і підтримуваний Google-сервіс, який є рекомендованим підходом для інтеграції MediaBrowser в Android. Він забезпечує зручне управління медіаконтентом і автоматично підтримує останні версії Android, що полегшує роботу з такими платформами, як Android Auto. Це найкращий вибір для нових проєктів, оскільки має нативну підтримку всіх необхідних функцій, а також можливість відтворення медіа без додаткового написання плеєра.
Під капотом рекомендується використовувати ExoPlayer, який, напевно, є оптимальним рішенням. Можна пробувати руками писати Media Player, але, скоріше за все, ви зіткнетеся з тим, що щось не працює, якісь формати не підтримуються тощо. Тому для реалізації рекомендую обирати ExoPlayer та MediaLibraryService.
Як підключати MediaLibraryService
Насправді це дуже просто:
- Потрібно задекларувати сервіс у маніфесті застосунку.
- Реалізувати MediaLibrary.Callback з двома методами для забезпечення базової сумісності з Android Auto.
Однак підтримки Android Auto на цьому етапі ще немає. Щоб підключити його, потрібно знову звернутися до маніфесту та додати рядки, які зазначають, що застосунок підтримує Android Auto для відтворення аудіо. У такому випадку застосунок буде сприйматися як сервіс, який підключається до Android Auto через MediaBrowser.
Його можна мінімально налаштувати: додати іконку, яка відображатиметься в автомобілі, або залишити стандартну іконку з вашого застосунку.
Коли ви підключили застосунок до Android Auto, ймовірно, він виглядатиме, як чорний екран. Далі розглянемо, як це налаштувати та перетворити на щось, схоже на скриншоти з документації Google.
Загалом вся робота відбувається через MediaItem. На кожному кроці Android Auto запитує дані через MediaLibrarySession.Callback, в якому потрібно повернути MediaItem. Він складається з кількох елементів, як-от ім’я артиста, назва треку, тривалість тощо. Вони можуть бути Browsable або Playable залежно від того, що відбувається при натисканні. Якщо це Playable, Item відтворюється; якщо Browsable — переходить у глибину ієрархії.
Налаштовуючи Android Auto, крім передачі MediaItem, також потрібно вказати параметри відображення за допомогою Library-параметрів. Проте слід розуміти, що ці параметри є лише хінтами — Android Auto може звертати на них увагу, а може й ні. У документації зазначено, що Library-параметри можуть підтримуватися на одних пристроях, але не підтримуватися на інших, хоч більшість із них зазвичай працюють на актуальних версіях Android Auto. Але це завжди може змінитися, і ніхто не може цього гарантувати.
Реалізація колбеків в Android Auto
Щоб реалізувати необхідні колбеки, потрібно визначити два основних методи. Перший — це onGetLibraryRoot, в якому потрібно віддати базовий елемент бібліотеки. Його важливо передати навіть з мінімальними параметрами. Ідеально, якщо цей root-елемент містить дефолтні налаштування, що дозволить підтримувати консистентний вигляд інтерфейсу, навіть якщо для деяких елементів параметри не задані.
Коли Android Auto запитує root, ви передаєте його через цей колбек. Далі система викликає getChildren, щоб отримати його дочірні елементи, та надсилає parentId root та параметр.
LibraryParams (які приходять в колбеці) — це механізм хінтів, який використовується для передачі специфічної інформації. Ви можете враховувати або ігнорувати його, але в цьому ж параметрі можна отримати інформацію від Android Auto про те, як відображаються ваші дані.
Відображення табів
Зазвичай у корені бібліотеки потрібно передати кілька вкладок, найчастіше — чотири. Щоб визначити точну кількість табів, які підтримує конкретна реалізація, можна скористатися переданими хінтами.
Налаштування вигляду елементів
Android Auto дозволяє налаштовувати вигляд кожного елемента, який ви відображаєте на екрані. Зараз підтримується чотири основних вигляди — два типи сітки та два типи списку. Найпоширенішими є базова сітка та список. Для відтворюваних елементів зазвичай використовують список, а для клікабельних елементів — сітку.
Кожен елемент можна налаштувати окремо, передаючи параметри Android Auto, і це буде лише рекомендацією — він може ці параметри врахувати або проігнорувати. Це залежить від реалізації, тому рекомендую протестувати вигляд після кожного оновлення Android Auto, адже деякі функції можуть змінитися або стати недоступними.
Групування елементів
Елементи можна об’єднувати в групи, додаючи заголовки за допомогою тих самих хінтів. Однак як і в попередніх випадках, немає гарантії, що ці налаштування завжди будуть враховані.
Метадані списків
В інтерфейсі Android Auto списки мають більш гнучкі налаштування, ніж сітка, і підтримують різні типи метаданих. Наприклад, ви можете позначити елементи як контент з обмеженим доступом, показати статус завантаження, вказати, чи це новий контент, і додати інші маркери, корисні для застосунків, таких як подкасти. Можна показувати час створення чи публікації, тривалість та прогрес відтворення. Ці метадані прив’язуються до кожного MediaItem, і прогрес відтворення може оновлюватись у реальному часі, якщо користувач повертається назад у меню під час відтворення.
Як тестувати ці функції
Тестування можна здійснити кількома способами:
Desktop Head Unit (DHU) — це емулятор Android Auto, який запускається на комп’ютері, а телефон виступає сервером. Для зручності раджу створити аліас у терміналі для швидкого запуску DHU. Перед кожним тестуванням потрібно стартувати сервер на телефоні. Детальніше про цей підхід в документації.
Реальний автомобіль — для цього потрібно увімкнути невідомі джерела в налаштуваннях розробника застосунку Android Auto. Це дозволить відобразити ваш застосунок в інтерфейсі автомобіля, якщо він ще не викладений у Play Market.
Media Controller Test — це тестовий інструмент від Google Lab, який дозволяє підключитися до застосунку та переглянути рендеринг контенту. Актуальну версію можна знайти в GitHub репозиторії androidx.media.
Ці три підходи дають можливість не тільки протестувати застосунок, але й переконатися, що Android Auto правильно сприймає ваші налаштування вигляду, метаданих і структури вкладок.
Підводні камені
Issue #167
Найпопулярніша проблема у бібліотеці медіа в Google. Коли ви додаєте підтримку MediaLibraryService, вас майже примусово змушують реалізувати метод для відновлення останнього відтвореного медіафайлу в застосунку. У такий спосіб користувачі отримують швидкий доступ до відтворення контенту при підключенні навушників або, наприклад, коли сідають в машину і запускають Android Auto. Якщо ви вирішите не реалізовувати цей метод, система загалом працюватиме, просто без функції відновлення.
Але є один виняток — телефони Samsung з 12 версією Android, які «вимагають» реалізації. Якщо цей метод не реалізований, застосунок крашиться. Рішення поки що немає, адже проблема в прошивці Samsung. Можливо, її буде виправлено в майбутніх оновленнях, але наразі ми змушені реалізовувати цей функціонал, щоб у користувачів з телефонами цієї версії не крашився застосунок.
Проте на реалізації методу історія не закінчується. Існують застосунки, у яких відтворення заборонене, якщо користувач не має підписки чи не авторизувався, тому вони також крашаться незалежно від того, чи реалізований метод. Щоби цього уникнути, можна додати невеликий аудіофайл з 1 мілісекундою тиші та віддавати його, щоб застосунок «думав», що все працює нормально. Це здається абсурдним, але наразі це єдине рішення.
Документація
Існує для MediaBrowserServiceCompat, але не для Media3, які частково відрізняються. Інструкції у старих документах часто неактуальні, особливо в частині констант і назв методів. Проте останнім часом її більш активно оновлюють, тому, можливо, згодом з’явиться повний гайд з Media3.
Пошук в Android Auto
Цей функціонал у новій бібліотеці включено за замовчуванням. Іконка пошуку може відображатись навіть якщо він не налаштований. Якщо він буде неактивним, це створює не найкращий користувацький досвід.
Пагінація
Загалом стандарт для мобільної розробки, але в Android Auto це трохи інша історія. Android Auto працює через медіабраузер, який не адаптований до підтримки пагінації, і постійно запитує першу сторінку з максимальним розміром. Поки що це обмеження можна лише прийняти, а повноцінна підтримка пагінації в Android Auto наразі недосяжна.
Відображення зображень
Android Auto працює з картинками через CenterCrop та може обрізати важливу частину зображення, якщо обкладинки не квадратні. Цю проблему можна обійти, створивши Content Provider, який повертає модифіковане зображення, наприклад, зі застосуванням Blur або FitCenter.
Одна з проблем, що виникла під час тестування, була в тому, що Android Auto кешує зображення при першому завантаженні. Якщо зробити зміни пізніше, користувач все одно побачить попередню версію картинки. Вирішити це можна шляхом очищення кешу або перезапуску емулятора Android Auto. Це забезпечує оновлення зображень у застосунку.
Висновок
Отже, якщо ви роздумуєте над додаванням підтримки Android Auto, і у вас є аудіофункціонал, рекомендую реалізовувати це одразу. Так, деякі труднощі є, але базову версію підтримки можна реалізувати швидко — налаштований UI та система хінтів дозволяють значно зекономити час на пошук безпечних рішень для розробки. І користувачі вам будуть дуже вдячні.
2 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарів