음성 비서 탭하여 읽기

Android Automotive에서는 음성을 운전 안전 상호작용의 중요한 구성요소이자 사용자가 운전 중에 Android Automotive OS와 상호작용할 수 있는 가장 안전한 방법 중 하나로 간주합니다. 그 결과, 운전 중에 수행하기 어려울 수 있는 사용자의 작업을 음성 도우미가 수행할 수 있도록 Android 음성 도우미 API( VoiceInteractionSession 포함)를 확장했습니다.

탭하여 읽기를 사용하면 사용자가 메시지 알림과 상호 작용할 때 음성 도우미가 사용자를 대신하여 문자 메시지를 읽고 답장할 수 있습니다. 이 기능을 제공하려면 음성 도우미를 CarVoiceInteractionSession 과 통합하면 됩니다.

Automotive에서 INBOX 또는 INBOX_IN_GROUP 으로 식별되는 알림 센터에 게시된 알림(예: SMS 메시지)에는 재생 버튼이 포함됩니다. 사용자는 재생을 클릭하여 선택한 음성 도우미가 알림을 소리내어 읽도록 하고 선택적으로 음성으로 응답할 수 있습니다.

탭하여 읽기 알림

그림 1. 재생 버튼이 있는 탭하여 읽기 알림.

CarVoiceInteractionSession과 통합

다음 섹션에서는 음성 도우미를 CarVoiceInteractionSession 과 통합하는 방법을 설명합니다.

음성 상호작용 지원

자동차 음성 상호작용 서비스를 제공하는 앱은 기존 Android 음성 상호작용과 통합 되어야 합니다 . 자세히 알아보려면 Android용 Google 어시스턴트를 참조하세요( VoiceInteractionSession 제외). 모든 음성 상호 작용 API 요소는 모바일 장치에 구현된 것과 동일하게 유지되지만 CarVoiceInteractionSession ( CarVoiceInteractionSession 구현 에 설명됨)이 VoiceInteractionSession 대체합니다. 자세한 내용은 다음 페이지를 참조하세요.

CarVoiceInteractionSession 구현

CarVoiceInteractionSession 음성 도우미가 문자 메시지를 큰 소리로 읽은 다음 사용자를 대신하여 해당 메시지에 응답할 수 있도록 하는 데 사용할 수 있는 API를 공개합니다.

CarVoiceInteractionSessionVoiceInteractionSession 클래스의 주요 차이점은 CarVoiceInteractionSession onShow 의 작업을 전달하므로 CarVoiceInteractionSession 이 세션을 시작하자마자 음성 도우미가 사용자 요청의 컨텍스트를 감지할 수 있다는 것입니다. 각 클래스의 onShow 매개변수는 다음 표에 나열되어 있습니다.

자동차음성상호작용세션 VoiceInteractionSession
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 열쇠로 소포 가능.
StatusBarNotification 에 매핑되는 KEY_NOTIFICATION
android.permission.BIND_NOTIFICATION_LISTENER_SERVICE 가 필요합니다.
사용자에게 응답 메시지를 명시하라는 메시지를 표시하고 보류 중인 인텐트의 RemoteInputReply 에 응답 메시지를 입력한 다음 보류 중인 인텐트를 실행합니다.
VOICE_ACTION_HANDLE_EXCEPTION 키가 포함된 문자열입니다.
ExceptionValue 에 매핑되는 KEY_EXCEPTION ( 예외 값 에 설명되어 있음)
부울 값에 매핑되는 KEY_FALLBACK_ASSISTANT_ENABLED . 값이 true 이면 사용자의 요청을 처리할 수 있는 대체 도우미가 비활성화된 것입니다.
예외에 대해 취해질 것으로 예상되는 조치는 예외에 대한 문서에 정의되어 있습니다.

예외 값

EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSINGManifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE 권한이 누락되었음을 음성 도우미에 알리고 사용자로부터 이 권한을 얻습니다.

알림 수신기 권한 요청

기본 음성 어시스턴트에 알림 수신기 권한이 없는 경우 플랫폼의 FallbackAssistant (자동차 제조업체에서 활성화한 경우)는 음성 어시스턴트에 권한 요청 알림을 보내기 전에 메시지를 소리내어 읽을 수 있습니다. FallbackAssistant 활성화되어 있고 메시지를 읽었는지 확인하려면 음성 도우미가 페이로드에서 KEY_FALLBACK_ASSISTANT_ENABLED 부울 값을 확인해야 합니다.

플랫폼에서는 이 권한이 요청되는 횟수만큼 음성 도우미에 속도 제한 논리를 추가할 것을 권장합니다. 이렇게 하면 음성 도우미에게 이 권한을 부여하고 싶지 않고 FallbackAssistant 가 문자 메시지를 소리내어 읽는 것을 선호하는 사용자를 존중합니다. 사용자가 메시지 알림에서 재생을 누를 때마다 사용자에게 권한을 요청하는 메시지는 부정적인 사용자 경험이 될 수 있습니다. 플랫폼은 음성 도우미를 대신하여 속도 제한을 부과하지 않습니다.

알림 청취자 권한을 요청할 때 음성 도우미는 CarUxRestrictionsManager 사용하여 사용자가 주차 중인지 운전 중인지 확인해야 합니다. 사용자가 운전 중인 경우 음성 도우미는 권한 부여 방법에 대한 지침을 제공하는 알림을 표시합니다. 그렇게 하면 사용자가 더 안전할 때 권한을 부여하는 데 도움이 되고 상기됩니다.

StatusBarNotification 작업

읽기 및 답장 음성 작업과 함께 전달된 StatusBarNotification 사용자에게 메시지 알림 에 설명된 대로 항상 자동차 호환 메시징 알림에 있습니다. 일부 알림에는 회신 보류 의도가 없을 수도 있지만 모두 읽음으로 표시 보류 의도가 있습니다.

알림과의 상호 작용을 간소화하려면 알림에서 메시지를 추출하고 알림의 적절한 보류 중인 인텐트에 응답 메시지를 쓰는 메서드를 제공하는 NotificationPayloadHandler 사용하세요. 음성 도우미가 메시지를 읽은 후 음성 도우미는 Mark as Read 의도를 실행 해야 합니다 .

탭하여 읽기 전제 조건 충족

사용자가 메시지를 읽고 답장하기 위해 음성 액션을 트리거하면 기본 음성 도우미의 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의 시퀀스 다이어그램.

앱 이름 읽기

음성 어시스턴트가 메시지를 읽는 동안 메시지 앱의 이름을 큰 소리로 읽도록 하려면(예: "행아웃의 Sam이 말했습니다...") 다음 코드 예제에 표시된 것과 같은 기능을 생성하여 어시스턴트가 메시지를 읽고 있는지 확인하세요. 정확한 이름:

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