Голосовой помощник

Android Automotive считает голосовую связь важнейшим компонентом безопасного взаимодействия при вождении и одним из самых безопасных способов взаимодействия пользователей с ОС Android Automotive во время вождения. В результате мы расширили API голосовых помощников Android (включая VoiceInteractionSession ), чтобы голосовые помощники могли выполнять для пользователей задачи, которые может быть сложно выполнить во время вождения.

Функция Tap-to-Read позволяет голосовым помощникам читать текстовые сообщения и отвечать на них от имени пользователя, когда пользователь взаимодействует с уведомлениями о сообщениях. Чтобы обеспечить эту функциональность, вы можете интегрировать голосового помощника с CarVoiceInteractionSession .

В автомобильной отрасли уведомления, публикуемые в Центре уведомлений с именем INBOX или INBOX_IN_GROUP (например, SMS-сообщения), включают кнопку «Воспроизвести» . Пользователь может нажать «Воспроизвести» , чтобы выбранный голосовой помощник прочитал уведомление вслух и, при необходимости, ответил голосом.

Уведомление о нажатии, чтобы прочитать

Рисунок 1. Уведомление «Tap-to-Read» с кнопкой «Воспроизвести».

Интеграция с CarVoiceInteractionSession

В следующих разделах описывается, как интегрировать голосового помощника с CarVoiceInteractionSession .

Поддержка голосового взаимодействия

Приложения, предоставляющие услуги голосового взаимодействия в автомобиле, должны интегрироваться с существующими голосовыми взаимодействиями Android. Чтобы узнать больше, см. Google Assistant для Android (за исключением VoiceInteractionSession ). Хотя все элементы API голосового взаимодействия остаются такими же, как реализованные на мобильных устройствах, CarVoiceInteractionSession (описанный в разделе «Реализация CarVoiceInteractionSession ») заменяет VoiceInteractionSession . Для получения дополнительной информации посетите эти страницы:

Реализация CarVoiceInteractionSession

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

Ключевое различие между классами CarVoiceInteractionSession и VoiceInteractionSession заключается в том, что CarVoiceInteractionSession передает действие в onShow , поэтому голосовой помощник может определить контекст запроса пользователя, как только CarVoiceInteractionSession запускает сеанс. Параметры onShow для каждого класса перечислены в следующей таблице:

АвтомобильГолосовоеВзаимодействиеСессия Сеанс голосового взаимодействия
onShow принимает эти три параметра:
  • args
  • showFlags
  • actions
onShow принимает эти два параметра:
  • args
  • showFlags

Изменения в Android 10

Начиная с Android 10, платформа вызывает VoiceInteractionService.onGetSupportedVoiceActions чтобы определить, какие действия поддерживаются. Голосовой помощник переопределяет и реализует VoiceInteractionService.onGetSupportedVoiceActions , как показано в следующем примере:

public class MyInteractionService extends VoiceInteractionService {
    private static final List SUPPORTED_VOICE_ACTIONS = Arrays.asList(
        CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION);

    @Override
    public Set onGetSupportedVoiceActions(@NonNull Set voiceActions) {
       Set result = new HashSet<>(voiceActions);
       result.retainAll(SUPPORTED_VOICE_ACTIONS);
       return result;
   }
}

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

Действие Ожидаемая полезная нагрузка Ожидаемое действие голосового взаимодействия
VOICE_ACTION_READ_NOTIFICATION Прочитайте сообщения вслух пользователю, а затем активируйте ожидающее намерение «Отметить как прочитанное», когда сообщения будут прочитаны успешно. При необходимости запросите у пользователя ответ.
VOICE_ACTION_REPLY_NOTIFICATION Возможна посылка с ключом.
KEY_NOTIFICATION , который соответствует StatusBarNotification .
Требуется android.permission.BIND_NOTIFICATION_LISTENER_SERVICE .
Предложите пользователю указать ответное сообщение, введите ответное сообщение в RemoteInputReply ожидающего намерения, а затем активируйте ожидающее намерение.
VOICE_ACTION_HANDLE_EXCEPTION Веревка с ключом.
KEY_EXCEPTION , который сопоставляется с ExceptionValue (описанным в разделе «Значения исключений» ).
KEY_FALLBACK_ASSISTANT_ENABLED , который соответствует логическому значению. Если значение равно true , резервный помощник, который может обработать запрос пользователя, отключен.
Ожидаемое действие, которое необходимо предпринять в отношении исключения, определено в документации по этому исключению.

Значения исключений

EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING указывает голосовому помощнику, что ему не хватает разрешения Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE и необходимо получить это разрешение от пользователя.

Запросить разрешение на прослушивание уведомлений

Если голосовой помощник по умолчанию не имеет разрешения на прослушивание уведомлений, FallbackAssistant платформы (если он включен производителем автомобиля) может прочитать сообщение вслух до того, как голосовой помощник получит уведомление о запросе разрешения. Чтобы определить, включен ли FallbackAssistant и прочитал ли сообщение, голосовой помощник должен проверить логическое значение KEY_FALLBACK_ASSISTANT_ENABLED в полезных данных.

Платформа рекомендует голосовому помощнику добавить логику ограничения скорости на количество раз, когда запрашивается это разрешение. Это уважает пользователя, который не хочет предоставлять голосовому помощнику это разрешение и предпочитает, чтобы FallbackAssistant читал текстовые сообщения вслух. Запрос у пользователя разрешения каждый раз, когда он нажимает «Воспроизвести» в уведомлении о сообщении, может быть негативным для пользователя. Платформа не накладывает ограничения на скорость голосового помощника.

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

Работа с StatusBarNotification

StatusBarNotification переданный вместе с голосовыми действиями «Читать» и «Ответить», всегда присутствует в уведомлении о сообщениях, совместимом с автомобилем, как описано в разделе «Уведомление пользователей о сообщениях» . Хотя некоторые уведомления могут не иметь намерения «Ожидание ответа», все они имеют ожидающее намерение «Отметить как прочитанное».

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

Соблюдение предварительных условий для чтения по касанию

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

Диаграммы последовательности

На этих рисунках показаны логические потоки CarVoiceInteractionSession actions :

VOICE_ACTION_READ_NOTIFICATION

Рисунок 2. Диаграмма последовательности для VOICE_ACTION_READ_NOTIFICATION.

В случае с Рисунком 3 рекомендуется применять ограничения скорости запросов на разрешения:

VOICE_ACTION_REPLY_NOTIFICATION

Рисунок 3. Диаграмма последовательности для VOICE_ACTION_REPLY_NOTIFICATION.

VOICE_ACTION_HANDLE_EXCEPTION

Рисунок 4. Диаграмма последовательности для VOICE_ACTION_HANDLE_EXCEPTION.

Прочитать название приложения

Если вы хотите, чтобы ваш голосовой помощник читал вслух имя приложения для обмена сообщениями во время чтения сообщения (например, «Сэм из Hangouts сказал...»), создайте функцию, подобную той, что показана в следующем примере кода, чтобы гарантировать, что помощник читает сообщение. правильное имя:

@Nullable
String getMessageApplicationName(Context context, StatusBarNotification statusBarNotification) {
    ApplicationInfo info = getApplicationInfo(context, statusBarNotification.getPackageName());
    if (info == null) return null;

    Notification notification = statusBarNotification.getNotification();

    // Sometimes system packages will post on behalf of other apps, so check this
    // field for a system app notification.
    if (isSystemApp(info)
            && notification.extras.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME)) {
        return notification.extras.getString(Notification.EXTRA_SUBSTITUTE_APP_NAME);
    } else {
        PackageManager pm = context.getPackageManager();
        return String.valueOf(pm.getApplicationLabel(info));
    }
}

@Nullable
ApplicationInfo getApplicationInfo(Context context, String packageName) {
    final PackageManager pm = context.getPackageManager();
    ApplicationInfo info;
    try {
        info = pm.getApplicationInfo(packageName, 0);
    } catch (PackageManager.NameNotFoundException e) {
        return null;
    }
    return info;
}

boolean isSystemApp(ApplicationInfo info) {
    return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}