Presionar para leer del asistente de voz

Android Automotive considera la voz como un componente crucial las interacciones seguras para conducir y una de las formas más seguras para que los usuarios interactuar con el SO Android Automotive mientras conduces Como resultado, ampliamos la APIs del asistente de voz de Android (incluidas VoiceInteractionSession) Para permitir que los asistentes de voz realicen tareas para los usuarios que pueden ser difíciles de lograr mientras se conduce.

La función Tocar para leer permite que los asistentes de voz lean y respondan los mensajes de texto en en nombre del usuario, cuando este interactúa con las notificaciones de mensajes. Para proporcionar esta funcionalidad, puedes integrar un asistente de voz con CarVoiceInteractionSession

En Automotive, las notificaciones publicadas en el Centro de notificaciones identificaron como INBOX o INBOX_IN_GROUP (por ejemplo, mensajes SMS) incluye un Botón Reproducir. El usuario puede hacer clic en Reproducir para seleccionar el asistente de voz lee la notificación en voz alta y, de manera opcional, responde con la voz.

Notificación de tocar para leer

Figura 1: Notificación de Presionar para leer con el botón Reproducir.

Cómo realizar la integración con CarVoiceInteractionSession

En las siguientes secciones, se describe cómo integrar un asistente de voz con CarVoiceInteractionSession

Cómo admitir interacciones de voz

Las apps que proporcionan servicios de interacción por voz en el vehículo deben integrarse con las interacciones de voz existentes de Android. Para obtener más información, consulta Asistente de Google para Android. (con la excepción de VoiceInteractionSession). Si bien toda la API de interacción de voz siguen siendo los mismos que se implementaron en los dispositivos móviles, CarVoiceInteractionSession (descrito en Cómo implementar CarVoiceInteractionSession), reemplaza VoiceInteractionSession Para obtener más información, consulta las siguientes páginas:

Cómo implementar CarVoiceInteractionSession

CarVoiceInteractionSession expone las APIs que puedes usar para permitir que los asistentes de voz lean mensajes de texto en voz alta y, luego, responder los mensajes en nombre del usuario.

La diferencia clave entre CarVoiceInteractionSession y VoiceInteractionSession clase es que CarVoiceInteractionSession pase en la acción en onShow para que el asistente de voz pueda detectar el contexto de la solicitud del usuario tan pronto como CarVoiceInteractionSession inicia una sesión. Los parámetros de onShow para cada clase se enumeran en la siguiente tabla:

CarVoiceInteractionSession VoiceInteractionSession
onShow toma estos tres parámetros:
  • args
  • showFlags
  • actions
onShow toma estos dos parámetros:
  • args
  • showFlags

Cambios en Android 10

A partir de Android 10, la plataforma llama a VoiceInteractionService.onGetSupportedVoiceActions para detectar qué acciones se admiten. El asistente de voz anula y implementa VoiceInteractionService.onGetSupportedVoiceActions, como se muestra en el siguiente ejemplo:

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;
   }
}

Las acciones válidas se describen en la siguiente tabla. Para obtener detalles sobre cada acción, consulta Diagramas de secuencias.

Acción Carga útil esperada Acción esperada de interacción de voz
VOICE_ACTION_READ_NOTIFICATION Leer los mensajes en voz alta para el usuario y, luego, activar la opción Marcar como leído pendiente cuando los mensajes se leen correctamente. De forma opcional, solicita usuario para que te brinde una respuesta.
VOICE_ACTION_REPLY_NOTIFICATION Parcelable con key.
KEY_NOTIFICATION que se asigna a StatusBarNotification.
Requiere android.permission.BIND_NOTIFICATION_LISTENER_SERVICE.
Solicita al usuario que indique el mensaje de respuesta, escribe el mensaje de respuesta en el RemoteInputReply del intent pendiente y, luego, activa el intent pendiente.
VOICE_ACTION_HANDLE_EXCEPTION String con clave.
KEY_EXCEPTION que se asigna a ExceptionValue (descritos en Valores de excepciones).
KEY_FALLBACK_ASSISTANT_ENABLED que se asigna a un valor booleano. Si el valor es true, el asistente de resguardo que puede controlar la solicitud del usuario inhabilitado.
La acción esperada que se debe tomar para la excepción se define en el documentación de la excepción.

Valores de excepción

EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING le indica al asistente de voz que falta el permiso Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE y que debe obtenerlo del usuario.

Solicita permiso de objeto de escucha de notificaciones

Si el asistente de voz predeterminado no tiene el objeto de escucha de notificaciones permiso, el objeto FallbackAssistant de la plataforma (si el fabricante del vehículo lo habilita), es posible que lea el mensaje en voz alta antes de que se active a quien se le notificó para solicitar el permiso. Para determinar si FallbackAssistant está habilitado leyó el mensaje, el asistente de voz debería revisar Valor booleano KEY_FALLBACK_ASSISTANT_ENABLED en la carga útil.

La plataforma recomienda que el asistente de voz agregue lógica de límite de frecuencia para la cantidad de veces que se solicita este permiso. Al hacerlo, se respeta al usuario que no deseas conceder al asistente de voz este permiso y prefiere la FallbackAssistant para leer mensajes de texto en voz alta. Hacer una solicitud al usuario para obtener permiso cada vez que presiona Reproducir en una notificación de mensaje puede generar una experiencia del usuario negativa. La plataforma no impone límites de frecuencia. en nombre del asistente de voz.

Al solicitar el permiso de objeto de escucha de notificaciones, el asistente de voz debe usa CarUxRestrictionsManager para determinar si un usuario está estacionado o conduciendo. Si el usuario está conduciendo, el asistente de voz muestra una notificación con instrucciones para otorgar el permiso. Hacerlo ayuda (y le recuerda) al usuario a otorgar el permiso cuando sea más seguro.

Cómo trabajar con StatusBarNotification

StatusBarNotification pasó con la función de lectura y respuesta las acciones de voz siempre están en una notificación de mensajería compatible con vehículos, como se describe en Notificar usuarios de mensajes. Si bien es posible que algunas notificaciones no tengan la respuesta pendiente todos tienen intents pendientes Marcar como leído.

Para optimizar las interacciones con las notificaciones, usa NotificationPayloadHandler, que proporciona métodos para extraer mensajes de la notificación y escribir el responder mensajes al intent pendiente adecuado de la notificación. Después del Asistente de voz lee el mensaje y debe activar la marca. como intent de lectura.

Cumplimiento de las condiciones previas de Tocar para leer

Solo el VoiceInteractionSession de la voz predeterminada el asistente recibe una notificación cuando un usuario activa la acción de voz para leer y responder mensajes. Como se mencionó anteriormente, este asistente de voz predeterminado también debe tener el permiso de objeto de escucha de notificaciones.

Diagramas de secuencias

Estas figuras muestran los flujos lógicos de CarVoiceInteractionSession actions:

VOICE_ACTION_READ_NOTIFICATION

Figura 2: Diagrama de secuencias de VOICE_ACTION_READ_NOTIFICATION.

En el caso de la Figura 3, se recomienda usar la app de límites de frecuencia para las solicitudes de permisos:

VOICE_ACTION_REPLY_NOTIFICATION

Figura 3: Diagrama de secuencias de VOICE_ACTION_REPLY_NOTIFICATION.

EXCEPCIÓN_DE_VOICE_ACTION_HANDLE_EXCEPTION

Figura 4: Diagrama de secuencias de VOICE_ACTION_HANDLE_EXCEPTION.

Leer el nombre de la app

Si deseas que el asistente de voz lea el nombre de la aplicación de mensajería en voz alta durante la (por ejemplo, "Sam de Hangouts dijo...") crea una función como la que se muestra en el siguiente ejemplo de código para asegurarte de que el asistente lea el nombre correcto:

@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;
}