Android Automotive OS позволяет пользователям устанавливать приложения в автомобиле. Чтобы охватить пользователей на этой платформе, вам необходимо распространить оптимизированное для водителя приложение, совместимое с Android Automotive OS. Вы можете повторно использовать почти весь код и ресурсы в своем приложении Android Auto, но вам необходимо создать отдельную сборку, которая соответствует требованиям на этой странице.
Обзор развития
Добавление поддержки Android Automotive OS требует всего нескольких шагов, как описано в следующих разделах:
- Включите автомобильные функции в Android Studio .
- Создать автомобильный модуль .
- Обновите зависимости Gradle .
- При желании можно реализовать настройки и действия по входу в систему .
- При желании ознакомьтесь с подсказками по размещению медиафайлов .
Соображения по дизайну
Android Automotive OS заботится о компоновке медиаконтента, который она получает от службы медиабраузера вашего приложения. Это означает, что ваше приложение не отрисовывает пользовательский интерфейс и не запускает никаких действий, когда пользователь запускает воспроизведение медиа.
Если вы реализуете настройки или действия входа , эти действия должны быть оптимизированы для транспортного средства . При проектировании этих областей вашего приложения обратитесь к Руководству по проектированию для Android Automotive OS.
Настройте свой проект
Вам необходимо настроить несколько частей проекта вашего приложения, чтобы включить поддержку Android Automotive OS.
Включить автомобильные функции в Android Studio
Используйте Android Studio 4.0 или более поздней версии, чтобы обеспечить включение всех функций автомобильной ОС.
Создать автомобильный модуль
Некоторые компоненты Android Automotive OS, такие как манифест, имеют специфические требования к платформе. Создайте модуль, который может хранить код для этих компонентов отдельно от другого кода в вашем проекте, например, кода, используемого для вашего приложения для телефона.
Чтобы добавить автомобильный модуль в свой проект, выполните следующие действия:
- В Android Studio нажмите Файл > Создать > Новый модуль .
- Выберите «Автомобильный модуль» , затем нажмите «Далее» .
- Введите имя приложения/библиотеки . Это имя, которое пользователи видят для вашего приложения на Android Automotive OS.
- Введите имя модуля .
- Измените имя пакета так, чтобы оно соответствовало вашему приложению.
Выберите API 28: Android 9.0 (Pie) для минимального SDK , затем нажмите Далее .
Все автомобили, поддерживающие Android Automotive OS, работают на базе Android 9 (уровень API 28) или выше, поэтому выбор этого значения касается всех совместимых автомобилей.
Выберите Нет активности , а затем нажмите Готово .
После создания модуля в Android Studio откройте AndroidManifest.xml
в новом автомобильном модуле:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.media">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" />
<uses-feature
android:name="android.hardware.type.automotive"
android:required="true" />
</manifest>
Элемент <application>
содержит некоторую стандартную информацию о приложении, а также элемент <uses-feature>
, который объявляет поддержку Android Automotive OS. Обратите внимание, что в манифесте не объявлено никаких действий.
Если вы реализуете настройки или действия входа , добавьте их здесь. Эти действия запускаются системой с использованием явных намерений и являются единственными действиями, которые вы объявляете в манифесте для вашего приложения Android Automotive OS.
После добавления любых настроек или действий по входу в систему завершите файл манифеста, установив атрибут android:appCategory
элемента <application>
на "audio"
.
<application
...
android:appCategory="audio" />
Объявить требования к функциям
Все приложения, созданные для Android Automotive OS, должны соответствовать определенным требованиям для распространения с помощью Google Play. Для получения дополнительной информации см. раздел Соответствие требованиям Google Play .
Объявить о поддержке мультимедиа для Android Automotive OS
Используйте следующую запись манифеста, чтобы объявить, что ваше приложение поддерживает Android Automotive OS:
<application>
...
<meta-data android:name="com.android.automotive"
android:resource="@xml/automotive_app_desc"/>
...
</application>
Эта запись манифеста относится к XML-файлу, в котором указаны автомобильные возможности, поддерживаемые вашим приложением.
Чтобы указать, что у вас есть медиа-приложение, добавьте XML-файл с именем automotive_app_desc.xml
в каталог res/xml/
вашего проекта. Включите в этот файл следующее содержимое:
<automotiveApp>
<uses name="media"/>
</automotiveApp>
Фильтры намерений
Android Automotive OS использует явные намерения для запуска действий в вашем медиа-приложении. Не включайте действия, имеющие фильтры намерений CATEGORY_LAUNCHER
или ACTION_MAIN
в файл манифеста.
Действия, подобные приведенному в следующем примере, обычно нацелены на телефон или другое мобильное устройство. Объявляйте эти действия в модуле, который создает приложение для телефона, а не в модуле, который создает приложение Android Automotive OS.
<activity android:name=".MyActivity">
<intent-filter>
<!-- You can't use either of these intents for Android Automotive OS -->
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!--
In their place, you can include other intent filters for any activities
that your app needs for Android Automotive OS, such as settings or
sign-in activities.
-->
</intent-filter>
</activity>
Обновите зависимости Gradle
Мы рекомендуем вам хранить службу медиабраузера в отдельном модуле, который вы используете совместно с вашим телефонным приложением и вашим автомобильным модулем. Если вы используете этот подход, вам необходимо обновить свой автомобильный модуль, чтобы включить общий модуль, как показано в следующем фрагменте:
my-auto-module /build.gradle
Круто
buildscript { ... dependencies { ... implementation project(':shared_module_name') } }
Котлин
buildscript { ... dependencies { ... implementation(project(":shared_module_name")) } }
Реализуйте настройки и действия по входу в систему
В дополнение к вашему сервису медиабраузера вы также можете предоставить оптимизированные для автомобиля настройки и действия входа для вашего приложения Android Automotive OS. Эти действия позволяют вам предоставлять функциональность приложения, которая не включена в Android Media API.
Реализуйте эти действия только в том случае, если вашему приложению Android Automotive OS необходимо разрешить пользователям входить в систему или указывать настройки приложения. Эти действия не используются Android Auto.
Рабочие процессы активности
На следующей схеме показано, как пользователь взаимодействует с вашими настройками и действиями по входу в систему с помощью Android Automotive OS:
Рисунок 1. Настройки и рабочие процессы входа в систему.
Не допускайте отвлекающих факторов в настройках и при входе в систему
Чтобы гарантировать, что ваши настройки и/или действия по входу в систему доступны для использования только во время парковки транспортного средства пользователя, убедитесь, что элемент(ы) <activity>
не включают следующий элемент <meta-data>
. Ваше приложение будет отклонено во время проверки, если такой элемент присутствует.
<!-- NOT ALLOWED -->
<meta-data
android:name="distractionOptimized"
android:value="true"/>
Добавить действие настроек
Вы можете добавить оптимизированную для автомобиля активность настроек, чтобы пользователи могли настраивать параметры вашего приложения в своем автомобиле. Ваша активность настроек также может предоставлять другие рабочие процессы, такие как вход в учетную запись пользователя или выход из нее или переключение учетных записей пользователей. Помните, что эта активность запускается только приложением, работающим на Android Automotive OS. Приложения для телефонов, подключенные к Android Auto, не используют ее.
Объявить действие настроек
Вам необходимо объявить активность настроек в файле манифеста вашего приложения, как показано в следующем фрагменте кода:
<application>
...
<activity android:name=".AppSettingsActivity"
android:exported="true"
android:theme="@style/SettingsActivity"
android:label="@string/app_settings_activity_title">
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
</intent-filter>
</activity>
...
</application>
Реализуйте ваши настройки активности
Когда пользователь запускает ваше приложение, Android Automotive OS обнаруживает объявленную вами активность настроек и отображает возможность, например значок. Пользователь может нажать или выбрать эту возможность с помощью дисплея своего автомобиля, чтобы перейти к активности. Android Automotive OS отправляет намерение ACTION_APPLICATION_PREFERENCES
, которое сообщает вашему приложению о необходимости запустить активность настроек.
В оставшейся части этого раздела показано, как можно адаптировать код из примера приложения Universal Android Music Player (UAMP) для реализации действия настроек для вашего приложения.
Для начала загрузите пример кода:
# Clone the UAMP repositorygit clone https://github.com/android/uamp.git
# Fetch the appropriate pull request to your local repositorygit fetch origin pull/323/head:NEW_LOCAL_BRANCH_NAME
# Switch to the new branchgit checkout NEW_LOCAL_BRANCH_NAME
Для реализации вашей деятельности выполните следующие действия:
- Скопируйте папку
automotive/automotive-lib
в ваш автомобильный модуль. - Определите дерево предпочтений, как в
automotive/src/main/res/xml/preferences.xml
. Реализуйте
PreferenceFragmentCompat
, который отображает ваша активность настроек. Для получения дополнительной информации см. файлыSettingsFragment.kt
иSettingsActivity.kt
в UAMP и руководство по настройкам Android .
При реализации настроек учтите следующие рекомендации по использованию некоторых компонентов библиотеки настроек:
- Не допускайте более двух уровней глубины вложения ниже основного представления в настройках.
- Не используйте
DropDownPreference
. Вместо этого используйтеListPreference
. - Организационные компоненты:
-
PreferenceScreen
- Это должен быть верхний уровень дерева ваших предпочтений.
-
PreferenceCategory
- Используется для группировки объектов
Preference
. - Укажите
title
.
- Используется для группировки объектов
-
- Включите
key
иtitle
во все следующие компоненты. Вы также можете включитьsummary
,icon
или и то, и другое:-
Preference
- Настройте логику в обратном вызове
onPreferenceTreeClick()
вашей реализацииPreferenceFragmentCompat
.
- Настройте логику в обратном вызове
-
CheckBoxPreference
- Вместо
summary
для условного текста можно использоватьsummaryOn
илиsummaryOff
.
- Вместо
-
SwitchPreference
- Вместо
summary
для условного текста можно использоватьsummaryOn
илиsummaryOff
. - Может иметь
switchTextOn
илиswitchTextOff
.
- Вместо
-
SeekBarPreference
- Включите
min
,max
иdefaultValue
.
- Включите
-
EditTextPreference
- Включите
dialogTitle
,positiveButtonText
иnegativeButtonText
. - Может иметь
dialogMessage
и/илиdialogLayoutResource
.
- Включите
-
com.example.android.uamp.automotive.lib.ListPreference
- В основном является производным от
ListPreference
. - Используется для отображения списка объектов
Preference
с одним выбором. - Должен иметь массив
entries
и соответствующих имentryValues
.
- В основном является производным от
-
com.example.android.uamp.automotive.lib.MultiSelectListPreference
- В основном происходит от
MultiSelectListPreference
- Используется для отображения списка объектов
Preference
с множественным выбором. - Должен иметь массив
entries
и соответствующих имentryValues
.
- В основном происходит от
-
Добавить действие входа в систему
Если ваше приложение требует, чтобы пользователь вошел в систему, прежде чем он сможет использовать ваше приложение, вы можете добавить оптимизированную для автомобиля активность входа, которая обрабатывает вход и выход из вашего приложения. Вы также можете добавить рабочие процессы входа и выхода в активность настроек , но используйте выделенную активность входа, если ваше приложение не может быть использовано, пока пользователь не войдет в систему. Помните, что эта активность запускается только приложением, работающим на Android Automotive OS. Приложения для телефонов, подключенные к Android Auto, не используют ее.
Требовать вход при запуске приложения
Чтобы потребовать от пользователя входа в систему перед использованием вашего приложения, ваш медиабраузер должен выполнить следующие действия:
- В методе
onLoadChildren()
вашей службы отправьтеnull
результат с помощью методаsendResult()
. - Установите
PlaybackStateCompat
медиа-сессии наSTATE_ERROR
с помощью методаsetState()
. Это сообщает Android Automotive OS, что никакие другие операции не могут быть выполнены, пока ошибка не будет устранена. - Установите код ошибки
PlaybackStateCompat
медиа-сеанса наERROR_CODE_AUTHENTICATION_EXPIRED
. Это сообщает Android Automotive OS, что пользователю необходимо пройти аутентификацию. - Установите сообщение об ошибке
PlaybackStateCompat
медиа-сессии с помощью методаsetErrorMessage()
. Поскольку это сообщение об ошибке обращено к пользователю, локализуйте его для текущей локали пользователя. Установите
PlaybackStateCompat
extras медиа-сессии с помощью методаsetExtras()
. Включите следующие два ключа:-
PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL
: строка, которая отображается на кнопке, которая начинает рабочий процесс входа. Поскольку эта строка отображается для пользователя, локализуйте ее для текущей локали пользователя. -
PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT
:PendingIntent
, который направляет пользователя к вашему действию входа в систему, когда пользователь нажимает кнопку, указанную вPLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL
.
-
В следующем фрагменте кода показано, как ваше приложение может потребовать от пользователя входа в систему перед использованием приложения:
Котлин
import androidx.media.utils.MediaConstants val signInIntent = Intent(this, SignInActivity::class.java) val signInActivityPendingIntent = PendingIntent.getActivity(this, 0, signInIntent, 0) val extras = Bundle().apply { putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL, "Sign in" ) putParcelable( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT, signInActivityPendingIntent ) } val playbackState = PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f) .setErrorMessage( PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED, "Authentication required" ) .setExtras(extras) .build() mediaSession.setPlaybackState(playbackState)
Ява
import androidx.media.utils.MediaConstants; Intent signInIntent = new Intent(this, SignInActivity.class); PendingIntent signInActivityPendingIntent = PendingIntent.getActivity(this, 0, signInIntent, 0); Bundle extras = new Bundle(); extras.putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL, "Sign in"); extras.putParcelable( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT, signInActivityPendingIntent); PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f) .setErrorMessage( PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED, "Authentication required" ) .setExtras(extras) .build(); mediaSession.setPlaybackState(playbackState);
После успешной аутентификации пользователя установите PlaybackStateCompat
обратно в состояние, отличное от STATE_ERROR
, а затем верните пользователя в Android Automotive OS, вызвав метод finish()
действия.
Реализуйте свою активность входа в систему
Google предлагает множество инструментов идентификации , которые вы можете использовать, чтобы помочь пользователям войти в ваше приложение в своих автомобилях. Некоторые инструменты, такие как Firebase Authentication, предоставляют полнофункциональные наборы инструментов, которые могут помочь вам создать настраиваемые возможности аутентификации. Другие инструменты используют существующие учетные данные пользователя или другие технологии, чтобы помочь вам создать бесперебойные возможности входа для пользователей.
Следующие инструменты помогут вам упростить процесс входа в систему для пользователей, которые ранее выполняли вход на другом устройстве:
- Вход и регистрация одним нажатием: если вы уже реализовали функцию One Tap для других устройств, например, для своего приложения для телефона, реализуйте ее для своего приложения Android Automotive OS, чтобы поддержать существующих пользователей One Tap.
- Вход через Google: если вы уже реализовали вход через Google для других устройств, например, для приложения на телефоне, реализуйте вход через Google для своего приложения Android Automotive OS, чтобы поддерживать существующих пользователей, использующих вход через Google.
- Автозаполнение с помощью Google: если пользователи включили функцию автозаполнения с помощью Google на других устройствах Android, их учетные данные сохраняются в менеджере паролей Google . Когда эти пользователи входят в ваше приложение Android Automotive OS, функция автозаполнения с помощью Google предлагает соответствующие сохраненные учетные данные. Использование функции автозаполнения с помощью Google не требует усилий по разработке приложения. Однако разработчики приложений могут оптимизировать свои приложения для получения более качественных результатов . Функция автозаполнения с помощью Google поддерживается всеми устройствами под управлением Android 8.0 (уровень API 26) или выше, включая Android Automotive OS.
Использовать AccountManager
Приложения Android Automotive OS, в которых есть аутентификация, должны использовать AccountManager по следующим причинам:
- Улучшенный пользовательский интерфейс и простота управления учетными записями: пользователи могут легко управлять всеми своими учетными записями из меню учетных записей в настройках системы, включая вход и выход.
- «Гостевой» опыт: автомобили являются общими устройствами, что означает, что OEM-производители могут включить «гостевой» опыт в автомобиле, где нельзя добавлять учетные записи. Это ограничение достигается с помощью
DISALLOW_MODIFY_ACCOUNTS
дляAccountManager
.
Разрешения
Если вам необходимо запросить разрешения у пользователя, используйте тот же поток, что и для действия аутентификации или действия настроек на схеме рабочих процессов действий, показанной в предыдущем разделе.
Запустите приложение-хостинг для медиа
Вы можете создать намерения для открытия приложения-хоста медиа для вашего приложения или контента в вашем приложении. Например:
- Ваше приложение может публиковать уведомление с ожидающим намерением, которое позволяет пользователю открыть ваше приложение, чтобы прослушать новый контент.
- Ваше приложение может обрабатывать глубокие ссылки и открывать хост-приложение в наиболее подходящем представлении.
Определить возможности медиа-хоста
Версии приложения медиа-хоста поддерживают различные возможности. Хосты указывают поддержку различных возможностей, включая фильтры намерений для следующих действий намерений:
Все приложения медиа-хостов поддерживают намерения MEDIA_TEMPLATE
. Чтобы определить, поддерживает ли медиа-хост намерения MEDIA_TEMPLATE_V2
, можно использовать queryIntentActivities()
следующим образом:
val isMediaTemplateV2Supported = packageManager.queryIntentActivities(
Intent(MediaIntentExtras.ACTION_MEDIA_TEMPLATE_V2),
// MATCH_DEFAULT_ONLY since the host should be started with implicit intents
// MATCH_SYSTEM_ONLY excludes any apps that aren't preinstalled
PackageManager.MATCH_DEFAULT_ONLY or PackageManager.MATCH_SYSTEM_ONLY
).size > 0
Создайте и используйте намерение
В зависимости от того, какие действия намерения поддерживаются хостом мультимедиа и каков ваш конкретный вариант использования, вы можете предоставить следующие дополнительные данные при создании намерения, которое вы используете для запуска приложения хоста мультимедиа.
Дополнительный ключ | Тип | Описание | Поддерживаемые действия |
---|---|---|---|
EXTRA_KEY_MEDIA_COMPONENT | String | Сглаженное имя компонента MediaBrowserService , к которому должно подключаться приложение хоста медиа — как правило, то, что нужно для вашего приложения. Если этот дополнительный компонент не указан, хост медиа по умолчанию использует активный источник медиа. | MEDIA_TEMPLATE , MEDIA_TEMPLATE_V2 |
EXTRA_KEY_SEARCH_QUERY | String | Поисковый запрос, который будет использоваться при вызове | MEDIA_TEMPLATE , MEDIA_TEMPLATE_V2 |
EXTRA_KEY_MEDIA_ID | String | Идентификатор носителя, который будет открыт в представлении просмотра. | MEDIA_TEMPLATE_V2 |
EXTRA_KEY_SEARCH_ACTION | Integer | Действие, которое необходимо выполнить после завершения поиска EXTRA_KEY_SEARCH_QUERY . | MEDIA_TEMPLATE_V2 |
Например, с хостом, который поддерживает действия MEDIA_TEMPLATE_V2
, следующий код откроет приложение медиа-хоста, подключит его к MyMediaBrowserService
, выполнит поиск по запросу "Jazz", а затем воспроизведет первый элемент из результатов поиска. На всех других хостах он только откроет приложение медиа-хоста и выполнит поиск по запросу "Jazz", предоставив пользователю возможность выбрать элемент для воспроизведения из результатов.
val startMediaHostIntent = Intent(ACTION_MEDIA_TEMPLATE)
.putExtra(MediaIntentExtras.EXTRA_KEY_MEDIA_COMPONENT, MyMediaBrowserService::class.java)
.putExtra(MediaIntentExtras.EXTRA_KEY_SEARCH_QUERY, "Jazz")
.putExtra(MediaIntentExtras.EXTRA_KEY_SEARCH_ACTION, MediaIntentExtras.EXTRA_VALUE_PLAY_FIRST_ITEM_FROM_SEARCH)
context.startActivity(startMediaHostIntent)
Поддержка глубоких ссылок
Чтобы улучшить работу вашего медиа-приложения на устройствах Android Automotive OS, вы можете добавить поддержку глубоких ссылок в свое приложение. Например, это позволяет пользователям открывать ваше приложение напрямую из браузера или при получении URL-адреса, отправленного с телефона с помощью Quick Share .
Добавить фильтры намерений глубоких ссылок
Чтобы сообщить ОС, что ваше приложение может обрабатывать глубокие ссылки, оно должно иметь действия с соответствующими фильтрами намерений. См. раздел Добавление фильтров намерений для входящих ссылок для получения руководства по формату фильтров намерений, используемых для глубоких ссылок.
Для лучшего пользовательского опыта поддерживайте все глубокие ссылки, которые поддерживает ваше мобильное приложение, если они могут быть разумно поддержаны вашим автомобильным приложением. Если в вашем приложении есть настройки или действия входа в систему, фильтры намерений для обработки настроек и глубоких ссылок входа в систему должны быть объявлены в соответствующих элементах манифеста <activity>
. Для воспроизведения мультимедиа и просмотра глубоких ссылок вы можете использовать действие батута, как описано далее в этом разделе.
Обработка намерений глубоких ссылок
Инструкции по чтению и реагированию на намерение, использованное для запуска активности вашего приложения, см. в разделе Чтение данных из входящих намерений.
Управление воспроизведением мультимедиа и просмотр глубоких ссылок
Поскольку пользовательский интерфейс для просмотра и воспроизведения рисуется хост-приложением, действие, используемое для обработки глубоких ссылок для действий воспроизведения и просмотра, не должно иметь собственного пользовательского интерфейса.
Вместо этого его следует в первую очередь использовать для создания и использования намерения для запуска приложения хоста мультимедиа . При необходимости он также может обрабатывать любые дополнительные изменения состояния вашего приложения, такие как добавление элементов мультимедиа в очередь. В следующем фрагменте показан пример реализации действия батута:
fun DeepLinkTrampolineActivity : ComponentActivity() {
override fun onCreate() {
handleIntent(intent)
}
override fun onNewIntent(intent: Intent) {
handleIntent(intent)
}
private fun handleIntent(intent: Intent) {
// Handle any side effects, such as adding a song to the queue
...
// Build the intent used to start the media host app
val startMediaHostIntent = ...
startActivity(intent)
// Finish the activity immediately so it isn't shown on screen
finish()
}
}
Читайте советы по размещению медиа-контента
В зависимости от системного приложения (включая его версию), которое подключается к вашему медиабраузеру, ваше приложение может получать следующие дополнительные возможности:
Обработка ошибок
Ошибки в медиаприложениях на Android Automotive OS передаются через PlaybackStateCompat
медиасеанса. Для всех ошибок установите соответствующий код ошибки и сообщение об ошибке в PlaybackStateCompat
. Это приведет к появлению Toast
в пользовательском интерфейсе.
Если произошла ошибка, но воспроизведение может продолжаться, выдайте нефатальную ошибку . Например, пользователь может воспроизводить музыку в приложении до входа в систему, но он должен войти в систему, прежде чем сможет пропустить песню. При использовании нефатальной ошибки система может предложить пользователю войти в систему, не прерывая воспроизведение текущего элемента мультимедиа.
При возникновении нефатальной ошибки сохраните остальную часть PlaybackStateCompat
как есть, за исключением кода ошибки и сообщения об ошибке. Использование этого подхода позволяет продолжить воспроизведение текущего элемента мультимедиа, пока пользователь решает, входить ли в систему.
Если воспроизведение невозможно, например, при отсутствии подключения к Интернету и отсутствии офлайн-контента, установите состояние PlaybackStateCompat
на STATE_ERROR
.
При последующих обновлениях PlaybackStateCompat
очистите все коды ошибок и сообщения об ошибках, чтобы избежать отображения нескольких предупреждений об одной и той же ошибке.
Если в какой-то момент вы не можете загрузить дерево просмотра, например, если требуется аутентификация, а пользователь не вошел в систему, отправьте пустое дерево просмотра. Чтобы обозначить это, верните нулевой результат из onLoadChildren()
для корневого узла медиа. Когда это происходит, система отображает ошибку на весь экран с сообщением об ошибке, установленным в PlaybackStateCompat
.
Ошибки, требующие исправления
Если ошибка требует принятия мер, дополнительно установите следующие два параметра в PlaybackStateCompat
:
-
PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL
: метка для кнопки, которую нужно нажать для устранения ошибки. Поскольку эта строка отображается пользователю, локализуйте ее для текущей локали пользователя. -
PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT
:PendingIntent
, который кнопка запускает для устранения ошибки, например, запуская действие входа в систему.
Ошибки, требующие устранения, отображаются в виде Dialog
и могут быть устранены пользователем только после остановки автомобиля.
Тестирование случаев ошибок
Убедитесь, что ваше приложение корректно обрабатывает ошибки во всех сценариях, включая:
- Различные уровни вашего продукта: например, бесплатный или премиум-уровень или с входом или без входа
- Различные состояния привода: например, припаркован и движется
- Различные состояния подключения: например, онлайн и офлайн
Другие соображения
При разработке приложения для Android Automotive OS учитывайте следующие моменты:
Оффлайн контент
Если применимо, реализуйте поддержку офлайн-воспроизведения. Автомобили с Android Automotive OS должны иметь собственное подключение к данным, то есть тарифный план должен быть включен в стоимость автомобиля или оплачиваться пользователем. Однако ожидается, что автомобили также будут иметь более изменчивое подключение, чем мобильные устройства.
Вот несколько вещей, которые следует учитывать при выборе стратегии офлайн-поддержки:
- Лучшее время для загрузки контента — когда ваше приложение используется.
- Не думайте, что WiFi доступен. Автомобиль может никогда не попасть в зону действия WiFi, или OEM-производитель мог отключить WiFi в пользу сотовой сети.
- Хотя разумное кэширование контента, который пользователи ожидают использовать, вполне допустимо, мы рекомендуем вам разрешить пользователю изменять это поведение с помощью настроек.
- Объем дискового пространства на автомобилях различается, поэтому предоставьте пользователям возможность удалять автономный контент, например, с помощью соответствующей опции в настройках.
Поддержка WebView
WebViews поддерживаются в Android Automotive OS, но разрешены только для ваших настроек и действий входа в систему. Действия, которые используют WebView, должны иметь возможность «закрыть» или «назад» за пределами WebView.
Вот несколько примеров приемлемых вариантов использования WebViews:
- Отображение вашей политики конфиденциальности, условий обслуживания или других ссылок юридического характера в ваших настройках.
- Веб-процесс входа в систему.
При использовании WebView вы можете включить Javascript .
Защитите свой WebView
Примите все возможные меры предосторожности, чтобы гарантировать, что ваш WebView не станет точкой входа в большой интернет. См. следующий фрагмент кода для примера того, как заблокировать WebView на URL, используемый в вызове loadUrl()
, и предотвратить перенаправления. Мы настоятельно рекомендуем вам реализовать такие меры предосторожности, когда это возможно, например, при отображении ссылок, связанных с законом.
Котлин
override fun shouldOverrideUrlLoading(webView: WebView, webResourceRequest: WebResourceRequest): Boolean { val originalUri: Uri = Uri.parse(webView.originalUrl) // Check for allowed URLs if (originalUri.equals(Uri.parse(BLANK_URL)) || originalUri.equals(webResourceRequest.url)) { return false } if (webResourceRequest.isRedirect) { logger.w("Redirect detected, not following") return true } setupWizardWebViewClientListener.onUriBlocked(webResourceRequest.url) logger.w( String.format( "Navigation prevented to %s original is %s", webResourceRequest.url, originalUri)) return true }
Ява
@Override public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest webResourceRequest) { Uri originalUri = Uri.parse(webView.getOriginalUrl()); // Check for allowed URLs if (originalUri.equals(Uri.parse(BLANK_URL)) || originalUri.equals(webResourceRequest.getUrl())) { return false; } if (webResourceRequest.isRedirect()) { logger.w("Redirect detected, not following"); return true; } setupWizardWebViewClientListener.onUriBlocked(webResourceRequest.getUrl()); logger.w( String.format( "Navigation prevented to %s original is %s", webResourceRequest.getUrl(), originalUri)); return true; }
Названия пакетов
Поскольку вы распространяете отдельный Android Package Kit (APK) для Android Automotive OS, вы можете повторно использовать имя пакета из вашего мобильного приложения или создать новое имя пакета. Если вы используете другое имя пакета, ваше приложение будет иметь два отдельных листинга в Play Store. Если вы повторно используете текущее имя пакета, ваше приложение будет иметь один листинг на обеих платформах.
Это преимущественно бизнес-решение. Например, если у вас есть одна команда, работающая над мобильным приложением, и отдельная команда, работающая над приложением Android Automotive OS, то может иметь смысл иметь отдельные имена пакетов и позволить каждой команде управлять своим собственным списком в Play Store. Нет большой разницы в технических усилиях, необходимых для использования любого из подходов.
В следующей таблице приведены некоторые другие ключевые различия между сохранением текущего имени пакета и использованием нового имени пакета:
Особенность | То же имя пакета | Новое имя пакета |
---|---|---|
Список магазинов | Одинокий | Несколько |
Зеркальная установка | Да: «быстрая переустановка приложения» во время работы мастера установки | Нет |
Процесс проверки Play Store | Блокировка обзоров: если обзор одного APK не пройден, другие APK, представленные в том же выпуске, блокируются. | Индивидуальные обзоры |
Статистика, метрики и показатели | Комбинированный: можно отфильтровать данные, относящиеся к автомобильной промышленности. | Отдельный |
Индексирование и поисковый рейтинг | Опирайтесь на текущее положение | Нет переноса |
Интеграция с другими приложениями | Скорее всего, никаких изменений не потребуется, если предположить, что медиа-код является общим для обоих APK. | Возможно, придется обновить соответствующее приложение, например, для воспроизведения URI с помощью Google Assistant. |
Часто задаваемые вопросы
В следующих разделах приведены ответы на некоторые часто задаваемые вопросы об Android Automotive OS.
Аппаратное обеспечение
Может ли мое приложение получить доступ к микрофону?
Для приложений, ориентированных на Android 10 (уровень API 29) или выше, обратитесь к документации по совместному использованию аудиовхода . Это невозможно до уровня API 29.
К каким автомобильным API мы можем получить доступ и как?
Вы ограничены API, которые предоставляет OEM. Разрабатываются процессы для стандартизации того, как вы получаете доступ к этим API.
Приложения могут получать доступ к автомобильным API с помощью SetProperty()
и GetProperty()
в CarPropertyManager
. Обратитесь к исходному коду или справочной документации , чтобы увидеть список всех доступных свойств. Если свойство аннотировано @SystemApi
, оно ограничено предварительно загруженными системными приложениями.
Какие типы аудиокодеков поддерживаются?
Подробную информацию об аудиокодеках смотрите в CDD Android.
Поддерживается ли Widevine DRM?
Да. Widevine DRM поддерживается.
Разработка и тестирование
Существуют ли какие-либо ограничения или рекомендации по использованию сторонних SDK и библиотек?
У нас нет конкретных рекомендаций по использованию сторонних SDK и библиотек. Если вы решите использовать сторонние SDK и библиотеки, вы все равно несете ответственность за соблюдение всех требований к качеству автомобильного приложения.
Могу ли я использовать службу переднего плана?
Единственный разрешенный вариант использования для службы переднего плана — загрузка контента для использования в автономном режиме. Если у вас есть другой вариант использования для службы переднего плана, для которого вы хотите получить поддержку, свяжитесь с нами через группу обсуждения Android Automotive OS .
Публикация приложений Android Automotive OS
Как опубликовать приложение Android Automotive OS с помощью Google Play Console?
Подробную информацию о том, как опубликовать приложение Android Automotive OS с помощью Google Play Console, см. в разделе Распространение в автомобилях .
Дополнительные ресурсы
Чтобы узнать больше об Android Automotive OS, ознакомьтесь со следующими дополнительными ресурсами.
Образцы
Руководства
- Дизайн для вождения
- Использование тестового приложения медиа-контроллера
- Уведомления на Android Automotive OS
- Качество Android-приложений для автомобилей
Блоги
- Обновления Android Automotive OS для разработчиков
- Разработка приложений для автомобильной ОС Android
Видео
- Как создавать медиа-приложения для автомобилей (Android Dev Summit '19)
- Как создавать приложения Android для автомобилей (Google I/O'19)
Сообщить о проблеме с Android Automotive OS Media
Если вы столкнулись с проблемой при разработке своего медиа-приложения для Android Automotive OS, вы можете сообщить о ней с помощью Google Issue Tracker . Обязательно заполните всю запрашиваемую информацию в шаблоне проблемы.
Перед тем, как подать новую проблему, проверьте, не отмечена ли она уже в списке проблем. Вы можете подписаться и проголосовать за проблемы, нажав на звездочку для проблемы в трекере. Для получения дополнительной информации см. Подписка на проблему .