앱 기본사항

자동차는 여러분의 캔버스입니다: 도로를 위한 Android 개발

스피커

정보

강연 소개

Android Auto 및 Android Automotive OS 차량에서 차량 내 디스플레이가 확대됨에 따라 개발자는 주차 중에는 풍부하고 적응형 환경을 제공하고, 운전 중에는 운전자에게 안전한 템플릿 기반 환경을 제공해야 하는 두 가지 과제에 직면해 있습니다. 이 포괄적인 30분 기술 세션에서는 Android 앱을 자동차에 맞게 조정하기 위한 엔드 투 엔드 아키텍처와 개발 접근 방식을 살펴봅니다.

자동차용 앱 설계의 기본 사항부터 자동차가 주행에서 주차로 전환될 때 오디오에서 동영상으로 전환되는 미디어 환경을 구축하는 최신 접근 방식에 이르기까지, 앱을 도로에 적용하는 데 필요한 모든 것을 알게 될 것입니다.

요약

  • 자동차용 Android는 Android Auto와 Android Automotive OS라는 두 가지 플랫폼을 타겟팅합니다. 하나는 휴대전화에서 투사되고 다른 하나는 차량에서 직접 실행됩니다.
  • 자동차 앱 라이브러리는 다양한 자동차 하드웨어 구성에 맞게 조정되는 운전에 최적화된 인터페이스용 템플릿을 제공합니다.
  • 주차된 자동차 앱은 동영상 스트리밍, 게임, 웹브라우저와 같은 풍부한 환경을 위해 표준 Android 활동을 사용합니다.
  • 자동차 앱 라이브러리 1.9에는 새로운 UI 구성요소와 브랜드 맞춤설정 토큰이 도입되었습니다. 또한 미디어 템플릿 지원을 Android Automotive OS로 완전히 확장합니다.
  • 주차-주행 기능은 주차 시 네이티브 동영상 활동을 동적으로 실행한 다음 주행 시 중단 없는 오디오를 유지하기 위해 미디어 템플릿으로 다시 전환합니다.

리소스

Gemini Notebook

주제

  • android-for-cars
  • android-auto
  • android-automotive-os
  • car-app-library
  • media3
  • parked-apps

스크립트

자동차용 Android 소개

  • 좋습니다.

  • 여러분, 환영합니다.

  • '자동차는 캔버스입니다' 세션에 참여해 주셔서 감사합니다.

  • 이 세션에서는 차량용 Android 개발을 시작하는 방법을 알아봅니다.

  • 저는 폴 람메르츠마입니다.

  • 저는 토마스 웨더스입니다.

  • 저희는 자동차용 Android팀의 개발자 관계 엔지니어입니다.

  • 많은 분들이 휴대전화, 폴더블, 태블릿 등 다양한 화면과 기기에서 앱이 멋지게 보이고 제대로 작동하도록 많은 시간과 노력을 기울이셨을 것입니다.

  • 오늘은 여러분이 생각하지 못했을 수도 있는 화면에 대해 알아보겠습니다.

  • 또한 독특한 방식으로 사용자에게 도달하는 데 도움이 될 수 있습니다.

  • 차량 내 디스플레이입니다.

  • 그럼 자동차용 Android가 무엇인지 간단히 살펴보겠습니다.

  • 자동차용 Android는 하나의 단일한 시스템이 아닙니다.

  • 타겟팅할 수 있는 플랫폼은 두 가지입니다.

  • 첫 번째는 휴대전화로 구동되는 프로젝션 시스템인 Android Auto입니다.

  • Android Auto를 사용하면 앱이 휴대전화에서 실행되고 유선 또는 무선 연결을 사용하여 UI를 차량 내 디스플레이에 투사합니다.

  • 두 번째는 Android Automotive OS입니다. 이는 차량 자체에서 직접 실행되는 Android의 변형입니다.

  • Android Automotive OS는 휴대전화와 독립적으로 실행되며, 차량 하드웨어, 냉난방, 라디오 등에 직접 액세스할 수 있고, 자체 데이터 연결도 관리합니다.

  • Android Automotive OS를 실행하는 자동차의 하위 집합은 Google 탑재 자동차입니다.

  • Google 탑재 자동차에는 Play 스토어, Gemini, Google 지도와 같은 Google 앱 및 서비스도 제공됩니다.

  • 두 플랫폼이 있지만, Google의 목표는 개발자가 한 번만 빌드하면 두 플랫폼 모두에서 우수한 환경을 제공하는 앱을 쉽게 배포할 수 있도록 하는 것입니다.

  • 다음은 자동차 앱 라이브러리를 사용하여 한 번 빌드된 미디어 앱의 예와 다양한 디스플레이 크기 및 모양의 Android Auto 및 Android Automotive OS에서 어떻게 표시되는지 보여줍니다.

  • 다양한 유형의 기기와 표시 경로를 대상으로 앱을 빌드할 수 있습니다.

  • 그렇다면 자동차는 왜 그럴까요?

  • 우선, 규모가 엄청나게 큽니다.

  • 현재 2억 5천만 대 이상의 Android Auto 호환 자동차가 운행 중이며, 16개 브랜드에서 100개 이상의 Google 탑재 자동차 모델을 제공하고 있습니다.

  • 앱이 자동차에 있으면 일상적인 출퇴근, 가족 활동을 위한 이동, 심부름, 자동차 여행 중에도 사용자에게 도달할 수 있습니다.

  • 미국자동차협회(AAA)의 2024년 미국 운전 설문조사에 따르면 미국 운전자는 하루 평균 60분을 운전하는 데 사용합니다.

  • 하지만 사용자가 운전 중일 때만 도달하는 것은 아닙니다.

  • 주차 중인 사용자에게도 도달할 수 있습니다.

  • 전기자동차 충전소에서 차량을 충전하거나 학교에서 자녀를 데리러 가기 위해 줄을 서서 기다리는 상황을 생각해 보세요.

  • 또한 승객 전용 디스플레이가 증가함에 따라 앞으로 사용자의 참여를 유도할 수 있는 기회가 더 많아질 것으로 예상됩니다.

  • 좋습니다.

  • 이제 자동차용으로 빌드할 수 있는 다양한 유형의 환경을 살펴보겠습니다.

  • 자동차용 앱을 빌드하는 방법을 이해하려면 차량 내부에서 앱이 실행될 때 존재하는 두 가지 주요 상황과 상태를 이해하는 것이 도움이 됩니다.

  • 첫 번째는 운전 중에 사용하는 앱입니다.

  • 차량이 움직이는 동안 사용할 수 있는 주행에 최적화된 환경입니다.

  • 여기에는 화면에 표시된 카테고리의 앱이 포함됩니다. 일반적으로 미디어라고 하는 오디오 앱, 메시지 및 커뮤니케이션 앱, 내비게이션 등이 있습니다.

  • 운전 최적화 환경은 엄격한 주의 분산 행동 보호 기준을 준수해야 합니다.

  • 차량이 움직이는 동안 안전하게 사용할 수 있도록 앱의 UI를 빌드하는 방법에는 특별한 고려사항이 있습니다.

  • 운전 최적화 앱을 빌드하는 방법에는 몇 가지가 있습니다.

자동차 앱 라이브러리 개요

  • 하지만 이번 세션에서는 자동차 앱 라이브러리를 사용하는 데 중점을 두겠습니다.

  • 이는 운전에 최적화된 사용자 인터페이스를 제공하는 템플릿 프레임워크를 제공하면서 자동차에 있는 다양한 하드웨어 구성에도 적응할 수 있는 Jetpack 라이브러리 세트입니다.

  • 입력 방식, 화면 크기, 가로세로 비율 등을 고려해야 합니다.

  • 자동차에 최적화된 운전 환경을 빌드하는 방법은 이 외에도 있지만, 이 강연에서는 자동차용 Android 앱 라이브러리를 사용하여 빌드하는 접근 방식에 중점을 두고자 합니다.

  • 이를 줄여서 CAL이라고 부르기도 합니다.

  • 앞서 언급했듯이 자동차 앱 라이브러리는 차량에서 사용할 앱을 빌드하는 데 도움이 되는 라이브러리 세트입니다.

  • 운전에 최적화된 사용자 인터페이스를 제공하면서 다양한 하드웨어 구성에 적응하는 작업을 처리하는 템플릿 프레임워크입니다.

  • 또한 Android Auto를 실행하든 Android Automotive OS를 실행하든 다양한 구성에서 앱이 잘 작동할 것이라고 확신할 수 있습니다.

  • CAL을 사용하여 빌드하는 앱은 이 호스트 클라이언트 아키텍처를 사용할 수 있습니다.

  • 호스트 앱(Android Auto 자체 또는 Google 탑재 자동차의 경우 Google Automotive App Host)은 시스템 렌더러입니다.

  • 궁극적으로 디스플레이에서 사용자에게 표시해야 하는 항목을 제어합니다.

  • 따라서 앱 개발자는 궁극적으로 픽셀을 그리지 않습니다.

  • 대신 구조화된 데이터와 데이터 상태를 자동차 앱 라이브러리 템플릿에 제공합니다.

  • 그러면 이 호스트가 이 데이터를 가져와 주의 분산 최적화 레이아웃을 사용하여 안전 규정을 준수하는 방식으로 안전하게 그립니다.

  • 그럼 CAL 내의 클래스, 즉 앱을 빌드하기 위해 확장해야 하는 클래스를 CarAppService부터 살펴보겠습니다.

  • 이는 호스트 애플리케이션이 클라이언트 앱과 통신하는 진입점 역할을 하는 Android 서비스의 서브클래스이며, 호스트가 상호작용하는 세션 인스턴스를 만드는 것이 목적입니다.

  • 세션은 차량의 디스플레이에서 실행되는 클라이언트 앱의 인스턴스라고 보면 됩니다.

  • 다른 Android 구성요소와 마찬가지로 자체 수명 주기가 있으며 이 수명 주기는 세션 인스턴스가 존재하는 동안 사용된 리소스를 초기화하고 해체하는 데 사용할 수 있습니다.

  • 이는 CarAppService와 세션 간의 일대다 관계입니다.

  • 예를 들어 CarAppService에는 세션 인스턴스가 두 개 있을 수 있습니다. 하나는 기본 디스플레이용이고 다른 하나는 계기판 화면을 지원하는 내비게이션 앱의 계기판 디스플레이용입니다.

  • 다음은 자동차에 기본 디스플레이와 계기판 디스플레이가 있고 각 디스플레이가 전용 세션과 연결된 예입니다. 앱 개발자는 이와 같은 방식으로 멀티 디스플레이 차량을 지원할 수 있습니다.

  • 그런 다음 세션 내에서 화면 인스턴스는 호스트 앱에서 렌더링된 사용자 인터페이스를 생성하는 역할을 담당합니다.

  • 이러한 사용자 인터페이스는 각각 특정 유형의 레이아웃(예: 그리드 또는 목록)을 모델링하는 템플릿 클래스로 표현됩니다.

  • 따라서 각 세션은 애플리케이션의 다양한 부분을 통한 사용자 플로우를 처리하는 화면 인스턴스 스택을 관리하며, 세션과 마찬가지로 화면에도 연결할 수 있는 자체 수명 주기가 있습니다.

  • 하지만 호스트가 UI를 렌더링하고 자동차 앱 라이브러리 템플릿을 사용한다고 해서 엄격한 제약이 있거나 애플리케이션을 맞춤설정할 수 없는 것은 아닙니다.

  • 사용할 수 있는 템플릿과 구성요소가 다양하며, 원하는 환경을 얻기 위해 조합할 수도 있습니다.

  • 자동차 앱 라이브러리 내의 모든 유형의 앱에서 사용할 수 있는 범용 템플릿이 있고, 내비게이션이나 관심 장소와 같은 특정 앱 환경을 위한 특수 목적 템플릿이 있습니다.

  • 하지만 운전에 최적화된 환경을 구축하는 방법을 자세히 알아보기 전에 자동차에서 애플리케이션을 실행할 수 있는 또 다른 상황인 주차 상태에 관해 살펴보겠습니다.

주차된 자동차용 앱 개발

  • 차량이 주차되어 있을 때만 사용할 수 있는 애플리케이션 카테고리가 있으며, 여기에는 동영상 앱, 게임, 브라우저 등이 포함됩니다.

  • 하지만 차량이 움직이지 않을 때는 운전자 주의 분산 행동 가이드라인이 해제되며 기존 적응형 UI에 더 부합하는 환경을 제공할 수 있습니다.

  • 주차된 앱은 활동 기반이며 휴대전화나 태블릿과 같은 다른 기기에서 사용되는 활동과 유사하거나 동일합니다. 주차된 앱에 관한 자세한 내용은 다음 섹션에서 설명합니다.

  • 주차 앱 환경은 기존의 적응형 활동을 재사용하지만, 매니페스트 선언과 디스플레이 컷아웃부터 자동차가 움직이기 시작할 때 재생을 일시중지하는 것까지 자동차에 특화된 품질 가이드라인을 충족해야 합니다.

  • 이 작업을 자동화하기 위해 Google은 주차된 앱을 위한 새로운 Android 스킬을 출시했습니다.

  • 시작하기 전에 Android CLI를 설치했는지 확인하세요. 이 짧은 링크에서 찾을 수 있습니다.

  • 설정이 완료되면 android skills list를 실행하여 사용 가능한 기술을 살펴봅니다.

    android skills list
    android skills add android-for-cars-parked-apps
  • Android 개발을 한 단계 더 발전시키는 데 사용할 수 있는 다양한 기술이 있습니다.

  • 자동차용 Android의 경우 android skills add android-for-cars-parked-apps를 사용하여 에이전트의 컨텍스트에 스킬을 추가할 수 있습니다.

  • 이제 어떤 AI 에이전트를 사용하든 Android Auto 또는 Android Automotive OS용 매니페스트를 구성하고, 자동차 창 인셋과 뒤로 탐색 등을 처리하고, 운전자 주의 분산 행동 재생 제한을 적용하는 방법에 관한 단계별 안내를 받을 수 있습니다. 또한 Google Play에 제출하기 전에 동영상, 게임 또는 브라우저 앱을 감사할 수도 있습니다.

자동차 앱 카테고리 개요

  • 자동차용 앱을 빌드하는 것도 앱 카테고리라는 개념 때문에 조금 독특합니다.

  • 앞서 언급했듯이 운전 중에 사용할 수 있는 앱 카테고리가 있고 주차 중에 사용할 수 있는 앱 카테고리가 있습니다.

  • 강조 표시된 카테고리는 운전 중에 사용할 수 있는 카테고리입니다.

  • 일부는 CAL로 표시되어 있습니다. 앞서 언급했듯이 이는 자동차 앱 라이브러리이며 이 카테고리의 앱은 조금 전에 살펴본 것과 같은 템플릿을 사용합니다.

  • 이제 이 내용을 빠르게 살펴보겠습니다. 자세히 설명하지는 않겠습니다.

  • 미디어 앱부터 살펴보겠습니다. 동영상이 아닌 오디오를 재생하는 앱입니다.

  • 빌드하는 방법에는 두 가지가 있습니다.

  • 여기 상단에 있는 MediaBrowserService는 가장 간단한 옵션입니다.

  • 개발자는 메타데이터를 제공하고 인포테인먼트 화면 인터페이스는 자동차에 최적화된 방식으로 재생 및 미디어 브라우저 UI를 렌더링합니다.

  • 다른 옵션은 자동차 앱 라이브러리를 사용하여 미디어 앱을 빌드하는 것입니다. 이 옵션을 사용하면 미디어 앱의 스타일과 표시 방식을 맞춤설정할 수 있는 더 많은 제어 기능과 옵션이 제공됩니다. 이에 관해서는 잠시 후에 토마스가 자세히 설명해 줄 것입니다.

  • 내비게이션 앱은 물론 경로와 세부 경로 안내를 제공하는 주요 사용 사례입니다.

  • 차량 공유 운전자 앱도 이 카테고리에 속합니다.

  • 관심 장소 앱을 사용하면 EV 충전기나 주차장과 같은 유용한 주변 장소를 찾을 수 있습니다.

  • 사물 인터넷 또는 IoT 앱을 사용하면 이동 중에도 스마트 기기에 액세스할 수 있습니다(예: 홈 관리).

  • 날씨 앱도 사용할 수 있으며 실시간 레이더, 폭풍 알림, 위치별 일기예보 등을 제공할 수 있습니다.

  • 마지막으로 커뮤니케이션은 기본 알림을 차량으로 확장하는 것, 메시지 앱, 영상 통화 앱의 세 가지 하위 카테고리로 나뉩니다.

  • 그리고 주차 카테고리에는 동영상 스트리밍 앱, 게임, 웹브라우저가 있습니다.

  • 몇 주 전부터 모든 개발자가 Android Auto 및 Android Automotive OS에 게임을 게시할 수 있게 되었다는 기쁜 소식을 전해 드립니다.

  • 이러한 카테고리 중 일부는 '공개', 일부는 '베타', 일부는 '출시 예정'으로 표시됩니다.

  • '공개'는 모든 개발자가 이 카테고리의 앱을 프로덕션에 바로 제출할 수 있음을 의미합니다.

  • 베타는 내부 또는 비공개 트랙에 게시할 수 있지만 사전 체험판 프로그램에 참여하지 않는 한 프로덕션에 앱을 게시할 수 없음을 의미합니다.

  • 각 카테고리의 문서에는 자세한 정보와 신청 양식 링크가 포함되어 있습니다.

  • '출시 예정'은 현재 지원되지 않지만 향후 지원할 계획이 있는 카테고리입니다.

  • 궁극적으로는 플랫폼을 통합하는 것이 목표입니다.

  • Google은 개발자가 카테고리와 관계없이 한 번만 작성하여 Android Auto와 Android Automotive OS 모두에 배포함으로써 최대한 많은 사용자에게 도달할 수 있도록 지원하고자 합니다.

  • 이제 토마스가 미디어에 관해 이야기하겠습니다.

자동차 앱 라이브러리 미디어 업데이트

  • 감사합니다.

  • 좋습니다.

  • 이에 따라 작년에 미디어 앱용 자동차 앱 라이브러리 버전 1.8을 도입하여 Android Auto에 템플릿 기반 탐색 UI와 맞춤 작업을 제공했습니다.

  • 여기에는 왼쪽에 표시된 미디어 재생 템플릿이 포함되었습니다.

  • 올해 I/O에서는 자동차 앱 라이브러리 1.9를 통해 더 많은 탐색 가능한 UI를 도입했습니다.

  • CAL 1.9가 베타에 도달함에 따라 이제 Auto 및 Automotive OS 전반에서 주요 기능 업데이트를 사용할 수 있습니다.

  • 주요 기능으로는 앱 표현을 통한 브랜드 맞춤설정이 있습니다. 이를 통해 안전 규칙을 유지하면서 호스트 렌더링 레이아웃으로 색상 및 도형 토큰을 맞춤설정할 수 있습니다. 또한 스포트라이트 섹션, 압축된 목록 항목, 스크롤 가능한 칩, 영구 미니플레이어와 같은 새로운 UI 구성요소도 제공됩니다.

  • 또한 CAL 1.9는 미디어 템플릿 지원을 AAOS로 완전히 확장하여 두 생태계 전반에서 진정한 플랫폼 통합을 실현합니다.

  • 자동차 앱 라이브러리의 다음 버전인 CAL 버전 10이 곧 출시될 예정입니다.

  • CAL 버전 10에서는 커뮤니케이션 앱을 위한 맞춤 템플릿이 추가되어 운전 중에도 더욱 강력하고 맞춤설정된 통화 환경을 제공합니다.

  • 또한 운전 중 대화형 환경을 제공하는 새로운 앱 카테고리와 앱 템플릿도 포함되어 있습니다.

  • 마지막으로, 자동차 앱 라이브러리 템플릿을 사용하여 주차에서 주행으로 더 원활하게 전환할 수 있는 더 많은 기능이 개발 중입니다.

  • 계속해서 더 많은 소식을 전해드릴 예정이니 기대해 주세요.

주차-주행 기능

  • 자동차 앱 라이브러리를 사용하는 주차-주행 전환 기능을 사용하면 앱이 정지 상태에서 모드를 동적으로 전환하고 적응형 콘텐츠를 표시하며, 주행 시 자동차 앱 라이브러리 템플릿으로 원활하게 다시 전환할 수 있습니다.

  • 주요 애플리케이션으로는 정지 상태일 때 맞춤 인증 흐름을 제공하거나, 동영상 팟캐스트 또는 음악 클립을 스트리밍하는 등 주차 전용 환경을 사용 설정하는 것이 있습니다.

  • 이는 미디어 재생 템플릿과 직접 통합됩니다.

  • 따라서 정지된 차량은 운전자에게 앱의 네이티브 Android 활동에 대한 전체 액세스 권한을 부여하여 동영상 스트리밍과 같은 리치 미디어를 지원합니다.

  • 차량의 기어가 변경되는 즉시 주의 분산 방지 기능이 작동하므로 앱이 자동차 앱 라이브러리 미디어 템플릿으로 다시 전환되어 규정을 준수하고 중단 없는 오디오 청취를 유지합니다.

  • 지금은 차량 내 환경이 혁신적으로 변화하는 시기입니다.

  • 미디어 앱은 기존의 탐색 및 재생 인터페이스를 넘어 운전자와 승객 모두에게 더 풍부하고 몰입감 있으며 상호작용이 가능한 순간을 제공하고자 합니다.

  • 이제 Media3 라이브러리를 사용하여 네이티브 동영상 활동을 추가하여 자동차가 주차 상태로 전환될 때 재생을 시작하는 방법의 예를 살펴보겠습니다.

  • 이를 시작하려면 동영상 렌더링 표시 경로를 백그라운드 재생 인스턴스에 직접 연결해야 합니다.

    override fun onStart() {
           super.onStart()
           ...
           controllerFuture = MediaController.Builder(
             this,
             sessionToken
           ).buildAsync()
    
           controllerFuture?.addListener({
               mediaController = controllerFuture?.get()
               playerView.player = mediaController
           }, ContextCompat.getMainExecutor(this))
    }
  • 이 활동 내에서 별도의 미디어 플레이어를 인스턴스화하지 않고, 오디오 및 동영상 스트림과 결합된 처리를 처리하는 Media3 미디어 라이브러리 서비스와 같은 기본 서비스 내에서 중앙 ExoPlayer 또는 미디어 플레이어를 유지하려고 합니다.

  • 따라서 이동 중에는 활성 서비스가 바인딩되지 않으므로 플레이어가 오디오만 디코딩하지만, 운전자가 주차 중에 동영상 활동을 열면 렌더링 노출 영역을 기본 서비스 플레이어에 직접 연결해야 합니다.

  • 따라서 Media3를 사용하면 mediaController가 플레이어를 기본적으로 구현하므로 여기에서 볼 수 있듯이 직접 할당이 가능합니다. playerView가 playerView.player를 mediaController에 직접 설정합니다.

  • 그런 다음 ParkedOnlyOnClickListener를 사용하여 네이티브 진입점을 등록해야 합니다.

    val watchVideoAction = Action.Builder()
      .setTitle("Watch Video")
      .setIcon(videoCarIcon)
      .setOnClickListener(
        ParkedOnlyOnClickListener.create {
          val intent = Intent(
            carContext,
            VideoPlayerActivity::class.java
          )
            .apply {
              addFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK
              )
            }
          carContext.startActivity(intent)
        })
      .build()
  • 이 래퍼는 미디어 재생 인터페이스의 헤더 표시줄 내에 인텐트 트리거를 제공합니다.

  • 따라서 동영상 재생을 실행하는 작업을 포함하고 선택 리스너를 ParkedOnlyOnClickListener로 래핑합니다.

  • 따라서 운전 모드에서는 이러한 탭이 호스트 앱에 의해 가로채지고 시스템 안전 메시지가 표시되므로 운전 중에는 해당 화면으로 이동할 수 없지만, 주차 중에는 콜백이 carContext 내에서 startActivity를 트리거하여 지정된 전체 화면 활동을 실행합니다.

  • 이러한 자동차 앱 라이브러리 앱에서는 운영체제가 주차 워크플로임을 인식할 수 있도록 매니페스트 내에서 동영상 타겟을 distractionOptimized=false로 플래그 지정해야 합니다.

    <activity
       android:name=".VideoPlayerActivity"
       android:exported="false"
       android:launchMode="singleTop">
       <meta-data
           android:name="distractionOptimized"
           android:value="false" />
    </activity>

주차에서 주행으로의 전환 처리

  • 마지막으로 운전자가 주차에서 주행으로 전환할 때 어떤 일이 발생하는지 살펴보겠습니다.

  • 활동이 주의 분산 최적화되지 않은 경우 자동차가 움직일 때 활성 상태로 유지되면 AAOS는 앱을 계속 사용하려면 주차하라는 시스템 차단 오버레이를 표시합니다.

  • 이러한 차단 화면을 방지하기 위해 오디오를 중단하지 않고 미디어 재생 템플릿으로 원활하게 돌아가는 것이 목표입니다.

  • 따라서 여기서 isRequiresDistractionOptimization가 true로 평가되면 기본 미디어 세션에서 동영상 렌더링 노출 영역을 지우고 플레이어 활동에서 finish를 호출합니다. CAL 환경 위에 실행되었기 때문에 완료하면 미디어 재생 템플릿으로 바로 돌아가 오디오 재생을 계속합니다.

    class VideoPlayerActivity : ComponentActivity(){
      override fun onStart() {
    
        …
    
        if (uxRestrictionsManager?
            .currentCarUxRestrictions?
            .isRequiresDistractionOptimization
                == true) {
          revertToCarAppTemplate()
        }
      }
    
      private fun revertToCarAppTemplate() {
        mediaControllerCompat
          .sendCommand("CMD_CLEAR_VIDEO_SURFACE",
                       null, null)
        finish()
      }
    }
  • 오디오가 끊김 없이 재생되도록 유지하는 것은 우수한 사용자 환경을 제공하는 데 핵심적인 요소입니다. 따라서 미디어 세션을 포그라운드 서비스로 활성 상태로 유지하면 이러한 상태 변경 중에도 사운드가 끊김 없이 계속 재생됩니다.

    <activity
            android:name="androidx.car.app.activity.CarAppActivity"
            android:exported="true"
            android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
    
            <action android:name="androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK" />
        </intent-filter>
        <meta-data
                android:name="distractionOptimized"
                android:value="true" />
    </activity>
  • 또한 CAL 화면에서 onNewIntent를 재정의하여 SHOW_MEDIA_PLAYBACK 인텐트를 캡처해야 합니다.

    class MyCarAppSession : Session() {
        override fun onCreateScreen(intent: Intent): Screen {
            // 1. Link your active MediaSession token with Car App Library's MediaPlaybackManager
            val mediaPlaybackManager = carContext.getCarService(MediaPlaybackManager::class.java)
            mediaPlaybackManager.registerMediaPlaybackToken(mediaSessionToken)
    
            // 2. Handle deep link if cold-started from the vehicle's media widget
            handlePlaybackIntent(intent)
            return HomeScreen(carContext)
        }
        override fun onNewIntent(intent: Intent) {
            super.onNewIntent(intent)
    
            // 3. Handle deep link when the session is already running
            handlePlaybackIntent(intent)
        }
    }
  • 이렇게 하면 사용자가 자동차 홈 화면에 있는 차량 시스템 미디어 위젯과 상호작용할 때마다 딥 링크를 통해 자동차 앱 라이브러리의 나우 플레잉 뷰로 바로 이동할 수 있습니다.

  • 따라서 개발 과정에서 이러한 전환을 검증하는 것은 매우 간단합니다.

  • AAOS에서 adb 명령어를 실행할 수 있습니다.

  • 이 경우 활동 간에 다시 전환할 준비가 되면 emulate-driving-state drive 또는 emulate-driving-state park입니다.

  • 다음은 자동차 앱 라이브러리를 사용하여 주차 중 동영상 재생 기능을 구현한 새로운 샘플 Media3 미디어 앱의 예입니다.

  • 아래층에 있는 적응형 Android 부스와 car-samples GitHub에서 곧 확인해 보세요.

  • 주차 중 사용 기능은 현재 Android Automotive OS에서 사용할 수 있으며, 이미 자동차 CAL과 통합된 미디어 앱의 경우 주행 환경에서 주차 중에도 더 강력한 환경을 제공할 수 있습니다.

  • 곧 developer.android.com의 문서에서 이 기능을 확인하고 앱에 이 기능을 적용하는 데 관심이 있다면 알려주세요.

  • 폴입니다.

자동차 앱 라이브러리에 추가될 기능

  • 좋습니다.

  • 토마스님, 감사합니다.

  • 마무리하기 전에 올해 말에 출시될 예정인 기능에 대해 자세히 알아볼 수 있는 몇 가지 방법을 알려드리겠습니다.

  • 토마스가 언급했듯이 CAL 1.9는 현재 알파 버전입니다.

  • 곧 베타 버전으로 전환될 예정입니다.

  • 그리고 CAL 1.10은 연말 전에 알파 단계에 진입할 예정이므로 대화형 UI와 최신 통신 및 주차-주행 기능을 평가할 수 있습니다.

  • 마지막으로, 앞서 언급했듯이 Android Auto와 Android Automotive OS에서 게임을 이용할 수 있게 되었습니다. 지금이 바로 자동차에 맞게 게임을 최적화할 수 있는 완벽한 시기입니다.

  • 구현 세부정보에 관한 자세한 내용은 '자동차용 게임 빌드' 가이드의 문서를 참고하세요.

  • '새로운 기능' 페이지에서 자동차에 맞게 게임을 조정하는 방법과 자동차용 Android의 새로운 기능 및 변경사항을 자세히 알아볼 수 있습니다.

  • 자동차와 사용자가 앱을 사용할 준비가 되어 있다는 것을 확인하셨기를 바랍니다.

  • 기존의 적응형 앱을 기반으로 주차 시 풍부한 경험을 제공하고, 다양한 자동차 앱 라이브러리 템플릿을 사용하여 안전 운전에 최적화된 경험을 만들 수 있습니다.

  • 게시하기 전에 데스크톱 헤드 유닛, 에뮬레이터, Pixel Tablet에서 실행되는 AAOS 또는 Firebase Test Lab을 사용하여 철저하게 테스트할 수 있습니다.

  • 여러분은 이미 이 생태계를 위한 앱을 빌드할 기술을 갖추고 있으며 수백만 대의 자동차가 여러분의 앱을 기다리고 있습니다. 그러니 앱을 출시해 보세요.

코드

코드 스니펫

'주차된 자동차용 앱 개발'의 09:03에 있는 셸 스니펫
android skills list
android skills add android-for-cars-parked-apps
'Park-to-drive 기능'의 15:20에 나오는 Kotlin 스니펫
override fun onStart() {
       super.onStart()
       ...
       controllerFuture = MediaController.Builder(
         this,
         sessionToken
       ).buildAsync()

       controllerFuture?.addListener({
           mediaController = controllerFuture?.get()
           playerView.player = mediaController
       }, ContextCompat.getMainExecutor(this))
}
'주차에서 주행으로 전환하는 기능'의 16:06에 나오는 Kotlin 스니펫
val watchVideoAction = Action.Builder()
  .setTitle("Watch Video")
  .setIcon(videoCarIcon)
  .setOnClickListener(
    ParkedOnlyOnClickListener.create {
      val intent = Intent(
        carContext,
        VideoPlayerActivity::class.java
      )
        .apply {
          addFlags(
            Intent.FLAG_ACTIVITY_NEW_TASK
          )
        }
      carContext.startActivity(intent)
    })
  .build()
'주차에서 주행으로 전환'의 16:42에 표시되는 XML 스니펫
<activity
   android:name=".VideoPlayerActivity"
   android:exported="false"
   android:launchMode="singleTop">
   <meta-data
       android:name="distractionOptimized"
       android:value="false" />
</activity>
'주차에서 주행으로의 전환 처리'의 17:17에 있는 Kotlin 스니펫
class VideoPlayerActivity : ComponentActivity(){
  override fun onStart() {

    …

    if (uxRestrictionsManager?
        .currentCarUxRestrictions?
        .isRequiresDistractionOptimization
            == true) {
      revertToCarAppTemplate()
    }
  }

  private fun revertToCarAppTemplate() {
    mediaControllerCompat
      .sendCommand("CMD_CLEAR_VIDEO_SURFACE",
                   null, null)
    finish()
  }
}
'주차에서 주행으로의 전환 처리'의 17:36에 나오는 XML 스니펫
<activity
        android:name="androidx.car.app.activity.CarAppActivity"
        android:exported="true"
        android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />

        <action android:name="androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK" />
    </intent-filter>
    <meta-data
            android:name="distractionOptimized"
            android:value="true" />
</activity>
'주차에서 주행으로의 전환 처리'의 17:49에 나오는 Kotlin 스니펫
class MyCarAppSession : Session() {
    override fun onCreateScreen(intent: Intent): Screen {
        // 1. Link your active MediaSession token with Car App Library's MediaPlaybackManager
        val mediaPlaybackManager = carContext.getCarService(MediaPlaybackManager::class.java)
        mediaPlaybackManager.registerMediaPlaybackToken(mediaSessionToken)

        // 2. Handle deep link if cold-started from the vehicle's media widget
        handlePlaybackIntent(intent)
        return HomeScreen(carContext)
    }
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)

        // 3. Handle deep link when the session is already running
        handlePlaybackIntent(intent)
    }
}