Instrument Cluster API(Android API)를 사용하여 Google 지도를 포함한 내비게이션 앱을 자동차의 보조 디스플레이(예: 핸들 뒤의 계기판)에 표시합니다. 이 페이지에서는
이를 통해 보조 디스플레이를 제어하고
CarService
- 내비게이션 앱에서
구성할 수 있습니다.
용어
이 페이지에서 사용되는 용어는 다음과 같습니다.
CarManager
의 인스턴스입니다.
Instrument Cluster로 연결되고 Instrument Cluster가 표시할 준비가 되면 콜백을 수신합니다.
있습니다.android:singleUser
속성이 있는 Android 서비스입니다. 위치
최대 1개의 서비스 인스턴스가 Android 시스템에서 실행됩니다.기본 요건
계속하기 전에 다음 요소가 있는지 확인합니다.
- Android 개발 환경. Android 개발 환경을 설정하려면 빌드 요구사항을 참고하세요.
- Android 소스 코드 다운로드. pi-car-release 브랜치의 최신 Android 소스 코드 버전(또는 이상)을 https://android.googlesource.com에서 가져옵니다.
- 헤드 단위 (HU). Android 9 이상을 실행할 수 있는 Android 기기입니다. 이 기기에는 자체 디스플레이가 있어야 하며 새로운 Android 빌드로 디스플레이를 플래시할 수 있어야 합니다.
- Instrument Cluster는 다음 중 하나입니다.
- HU에 연결된 물리적 보조 디스플레이. 만약 기기 하드웨어 및 커널이 다중 디스플레이 관리를 지원합니다.
- 독립적인 단위. 네트워크 연결을 통해 HU에 연결된 전산 단위로, 자체 디스플레이에서 동영상 스트림을 수신하고 표시할 수 있습니다.
- 에뮬레이션된 디스플레이. 개발 중에 다음 에뮬레이션된 환경 중 하나를 사용할 수 있습니다.
- 시뮬레이션된 보조 디스플레이. 시뮬레이션된 개발자 옵션으로 이동 설정 시스템 앱에서 설정을 클릭한 다음 보조 시뮬레이션을 선택합니다. 디스플레이 이 구성은 물리적 보조 장치를 이 디스플레이가 기본 화면 위에 겹쳐서 표시되는데, 디스플레이.
- 에뮬레이션된 계기판. Android Emulator 포함 AAOS는 계기판을 표시하는 옵션을 제공합니다. ClusterRenderingService를 만듭니다.
통합 아키텍처
통합 구성요소
Instrument Cluster API 통합은 다음 3개 구성요소로 구성됩니다.
CarService
- 내비게이션 앱
- OEM Instrument Cluster 서비스
CarService
CarService
는 내비게이션 앱과 자동차 간에 중재하여 언제든지 하나의 내비게이션 앱만 활성화되고 android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL
권한이 있는 앱만 자동차에 데이터를 보낼 수 있도록 합니다.
CarService
는 모든 자동차 관련 서비스를 부트스트랩하고 일련의 관리자를 통해 관련 서비스에 액세스할 수 있는 권한을 제공합니다. 서비스와 상호작용하려면
자동차에서 실행되는 앱은 이러한 관리자에 액세스할 수 있습니다.
계기판 구현의 경우 자동차 OEM은 InstrumentClusterRendererService의 구현을 제공하고 ClusterRenderingService를 만듭니다.
Instrument Cluster를 렌더링할 때 부팅 프로세스 중에
CarService
는 다음 객체의 InstrumentClusterRendererService
키를 읽습니다.
ClusterRenderingService
InstrumentClusterService
의 구현을 찾습니다. AOSP에서 이 항목은 Navigation State API 샘플 클러스터 구현 렌더링 서비스를 가리킵니다.
<string name="instrumentClusterRendererService"> android.car.cluster/.ClusterRenderingService </string>
이 항목에서 참조된 서비스는 초기화되고 CarService
에 바인드됩니다. Google 지도와 같은 내비게이션 앱이 CarInstrumentClusterManager
를 요청하면 CarService
는 바인드된 InstrumentClusterRenderingService
에서 Instrument Cluster 상태를 업데이트하는 관리자를 제공합니다.
이 경우 바인드는 Android 서비스를 나타냅니다.
Instrument Cluster 서비스
OEM은 ClusterRenderingService를 만듭니다.
이 클래스는 다음 두 가지 목적으로 사용됩니다.
- Android 및 Instrument Cluster 렌더링 기기 인터페이스를 제공합니다. (이 페이지의 목적)
- 세부 경로 안내와 같은 내비게이션 상태 업데이트를 수신하고 렌더링합니다. 탐색 안내를 참조하세요.
첫 번째 목적으로, InstrumentClusterRendererService
의 OEM 구현은 차량 실내에서 화면에 정보를 렌더링하고 InstrumentClusterRendererService.setClusterActivityOptions()
및 InstrumentClusterRendererService.setClusterActivityState()
메서드를 호출하여 이 정보를 CarService
에 전달하는 데 사용되는 보조 디스플레이를 초기화해야 합니다.
두 번째 기능의 경우 Instrument Cluster 서비스는
Google Cloud 콘솔의
ClusterRenderingService(클러스터 렌더링 서비스)
탐색 상태 업데이트 이벤트를 수신하는 인터페이스입니다. 이 이벤트는
번들에 인코딩된 eventType
및 이벤트 데이터
통합 시퀀스
다음 다이어그램은 업데이트를 렌더링하는 탐색 상태의 구현을 보여 줍니다.
이 삽화에서 색상은 다음을 나타냅니다.
- 노란색. Android 플랫폼에서 제공하는
CarService
및CarNavigationStatusManager
입니다. 자세한 내용은 자동차 및 CAR_NAVIGATION_SERVICE를 참고하세요. - 녹청색. OEM에서 구현하는
InstrumentClusterRendererService
입니다. - 자주색. Google 및 서드 파티 개발자가 구현하는 네비게이션 앱입니다.
- 녹색.
CarAppFocusManager
입니다. 자세한 내용은 아래의 CarAppFocusManager API 사용과 CarAppFocusManager를 참고하세요.
탐색 상태 정보 흐름은 다음 시퀀스를 따릅니다.
CarService
는InstrumentClusterRenderingService
를 초기화합니다.- 초기화 중에
InstrumentClusterRenderingService
는CarService
를 다음으로 업데이트합니다.- 뚜렷한 경계와 같은 Instrument Cluster 디스플레이 속성입니다(나중에 뚜렷한 경계에 관한 자세한 내용 참고).
- Instrument Cluster 디스플레이 내에서 활동을 시작하는 데 필요한 활동 옵션입니다. 자세한 내용은 ActivityOptions에서 사용할 수 있습니다.
- 내비게이션 앱 (예: Android Automotive용 Google 지도 또는 모든 지도 앱)
권한이 있는 사용자)에 액세스할 수 있습니다.
<ph type="x-smartling-placeholder">
- </ph>
- car-lib에서 Car 클래스를 사용하여
CarAppFocusManager
를 가져옵니다. - 세부 경로 안내가 시작되기 전에
통과까지
CarAppFocusManager.requestFocus()
남음appType
(으)로CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION
매개변수 값으로 사용됩니다.
- car-lib에서 Car 클래스를 사용하여
CarAppFocusManager
가 이 요청을CarService
에 전달합니다. 권한이 부여된 경우CarService
는 내비게이션 앱 패키지를 검사하고android.car.cluster.NAVIGATION
카테고리로 표시된 활동을 찾습니다.- 찾은 경우 내비게이션 앱은
ActivityOptions
활동을 실행하고 다음을 포함하는InstrumentClusterRenderingService
인텐트에 Extras로 표시되는 Instrument Cluster 디스플레이 속성입니다.
API 통합
InstrumentClusterRenderingService
구현은 다음을 충족해야 합니다.
- 다음 값을
AndroidManifest.xml로 설정합니다 이는
Instrument Cluster 서비스는 초기화 및 사용자 전환 중에도 실행됩니다.
android:singleUser="true"
BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE
시스템 권한을 보유해야 합니다. 이렇게 하면 Android 시스템 이미지의 일부로 포함된 Instrument Cluster 렌더링 서비스만CarService
에 바인드됩니다.<uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
InstrumentClusterRenderingService 구현
서비스를 빌드하려면:
- 다음에서 확장되는 클래스 작성
ClusterRenderingService(클러스터 렌더링 서비스)
그런 다음 상응하는 항목을
AndroidManifest.xml
파일에 추가합니다. 이 수업 계기판 디스플레이를 제어하고 (필요한 경우) 내비게이션 상태를 렌더링할 수 있습니다. API 데이터입니다. onCreate()
중에 이 서비스를 사용하여 사용할 수 있습니다. 다음과 같은 옵션이 있습니다.- Instrument Cluster에 사용할 보조 디스플레이를 결정합니다.
- Instrument Cluster 앱이 다음을 렌더링하고 전송하도록 가상 디스플레이를 만듭니다. 이미지를 외부 장치에 보냅니다 (H.264 등의 동영상 스트리밍 형식 사용).
- 위에 표시된 디스플레이가 준비되면 이 서비스는
InstrumentClusterRenderingService#setClusterActivityLaunchOptions()
를 호출하여 Instrument Cluster에서 활동을 표시하는 데 사용해야 하는 정확한ActivityOptions
를 정의해야 합니다. 다음 매개변수를 사용합니다.category.
ClusterRenderingService입니다.ActivityOptions.
Instrument Cluster에서 활동을 시작하는 데 사용할 수 있는ActivityOptions
인스턴스입니다. 예를 들어 AOSP의 샘플 Instrument Cluster 구현에서 시작합니다.getService().setClusterActivityLaunchOptions( CATEGORY_NAVIGATION, ActivityOptions.makeBasic() .setLaunchDisplayId(displayId));
- Instrument Cluster가 활동을 표시할 준비가 되면 이 서비스는
InstrumentClusterRenderingService#setClusterActivityState()
를 호출해야 합니다. 다음 매개변수를 사용합니다.category
ClusterRenderingService입니다.- 다음으로 생성된 번들
state
개 ClusterRenderingService입니다. 다음 데이터를 제공해야 합니다. <ph type="x-smartling-placeholder">- </ph>
visible
Instrument Cluster를 공개 가능 및 콘텐츠 표시 가능으로 지정합니다.unobscuredBounds
콘텐츠를 안전하게 표시할 수 있는 Instrument Cluster 디스플레이 내 영역을 정의하는 직사각형입니다. 다이얼 및 게이지가 적용되는 영역을 예로 들 수 있습니다.
Service#dump()
메서드를 재정의하고 디버깅에 유용한 상태 정보를 보고합니다(자세한 내용은 dumpsys 참고).
샘플 InstrumentClusterRenderingService 구현
다음 예에서는 원격 물리적 디스플레이에 Instrument Cluster 콘텐츠를 표시할 VirtualDisplay
를 만드는 InstrumentClusterRenderingService
구현을 개략적으로 보여 줍니다.
또는 이 코드는 HU에 연결된 물리적 보조 디스플레이의 displayId
를 전달할 수 있습니다(사용 가능한 것으로 알려진 경우).
/** * Sample {@link InstrumentClusterRenderingService} implementation */ public class SampleClusterServiceImpl extends InstrumentClusterRenderingService { // Used to retrieve or create displays private final DisplayManager mDisplayManager; // Unique identifier for the display to be used for instrument // cluster private final String mUniqueId = UUID.randomUUID().toString(); // Format of the instrument cluster display private static final int DISPLAY_WIDTH = 1280; private static final int DISPLAY_HEIGHT = 720; private static final int DISPLAY_DPI = 320; // Area not covered by instruments private static final int DISPLAY_UNOBSCURED_LEFT = 40; private static final int DISPLAY_UNOBSCURED_TOP = 0; private static final int DISPLAY_UNOBSCURED_RIGHT = 1200; private static final int DISPLAY_UNOBSCURED_BOTTOM = 680; @Override public void onCreate() { super.onCreate(); // Create a virtual display to render instrument cluster activities on mDisplayManager = getSystemService(DisplayManager.class); VirtualDisplay display = mDisplayManager.createVirtualDisplay( mUniqueId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DPI, null, 0 /* flags */, null, null); // Do any additional initialization (e.g.: start a video stream // based on this virtual display to present activities on a remote // display). onDisplayReady(display.getDisplay()); } private void onDisplayReady(Display display) { // Report activity options that should be used to launch activities on // the instrument cluster. String category = CarInstrumentClusterManager.CATEGORY_NAVIGATION; ActionOptions options = ActivityOptions.makeBasic() .setLaunchDisplayId(display.getDisplayId()); setClusterActivityOptions(category, options); // Report instrument cluster state. Rect unobscuredBounds = new Rect(DISPLAY_UNOBSCURED_LEFT, DISPLAY_UNOBSCURED_TOP, DISPLAY_UNOBSCURED_RIGHT, DISPLAY_UNOBSCURED_BOTTOM); boolean visible = true; ClusterActivityState state = ClusterActivityState.create(visible, unobscuredBounds); setClusterActivityState(category, options); } }
CarAppFocusManager API 사용
CarAppFocusManager API는 getAppTypeOwner()
메서드를 제공합니다.
특정 시점에 탐색 포커스가 있는 내비게이션 앱을 파악하기 위해 OEM에서 작성한 클러스터 서비스
있습니다. OEM은 기존 CarAppFocusManager#addFocusListener()
메서드를 사용할 수 있습니다.
그런 다음 getAppTypeOwner()
를 사용하여 포커스가 있는 앱을 알아봅니다. 이 정보를 바탕으로
OEM은 다음을 수행할 수 있습니다.
- 클러스터에 표시된 활동을 포커스를 보유한 내비게이션 앱에서 제공하는 클러스터 활동으로 전환할 수 있습니다.
- 포커스가 지정된 내비게이션 앱에 클러스터 활동이 있는지 감지할 수 있습니다. 포커스가 내비게이션 앱에 클러스터 활동이 없거나 이러한 활동이 사용 중지된 경우 OEM은 이 신호를 자동차 DIM에 보내 클러스터의 내비게이션 패싯을 완전히 건너뜁니다.
CarAppFocusManager
를 사용하여 현재 앱 포커스를 설정하고 수신 대기합니다. 예를 들면 다음과 같습니다.
활성 내비게이션이나 음성 명령이 표시되지 않습니다. 일반적으로 이러한 앱의 인스턴스는 하나만 활성 상태입니다.
집중할 수 있습니다
CarAppFocusManager#addFocusListener(..)
메서드를 사용하여 앱 포커스 변경을 리슨합니다.
import android.car.CarAppFocusManager; ... Car car = Car.createCar(this); mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE); mAppFocusManager.addFocusListener(this, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); ... public void onAppFocusChanged(int appType, boolean active) { // Use the CarAppFocusManager#getAppTypeOwner(appType) method call // to retrieve a list of active package names }
CarAppFocusManager#getAppTypeOwner(..)
메서드를 사용하여 패키지를 검색합니다.
포커스가 지정된 특정 앱 유형의 현재 소유자의 이름 현재 소유자가 android:sharedUserId
기능을 사용하는 경우 이 메서드는 패키지 이름을 두 개 이상 반환할 수 있습니다.
import android.car.CarAppFocusManager; ... Car car = Car.createCar(this); mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE); List<String> focusOwnerPackageNames = mAppFocusManager.getAppTypeOwner( CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION); if (focusOwnerPackageNames == null || focusOwnerPackageNames.isEmpty()) { // No Navigation app has focus // OEM may choose to show their default cluster view } else { // focusOwnerPackageNames // Use the PackageManager to retrieve the cluster activity for the package(s) // returned in focusOwnerPackageNames } ...
부록: 샘플 앱 사용
AOSP는 Navigation State API를 구현하는 샘플 앱을 제공합니다.
이 샘플 앱을 실행하는 방법은 다음과 같습니다.
- 지원되는 HU에서 Android Auto를 빌드하고 플래시합니다. 사용 중인 기기와 관련된 Android 빌드 및 플래시 안내를 사용합니다. 자세한 내용은 참조 보드 사용을 참고하세요.
- 물리적 보조 디스플레이를 HU (지원되는 경우)에 연결하거나 가상 디스플레이를 켭니다.
보조 HU:
<ph type="x-smartling-placeholder">
- </ph>
- 설정 앱에서 개발자 모드를 선택합니다.
- 설정 > 시스템 > 고급 > 개발자 옵션 > 보조 디스플레이 시뮬레이션하기
- HU 재부팅
- KitchenSink 앱을 실행하려면 다음 단계를 따르세요.
- 창을 엽니다.
- Instrument Cluster로 이동합니다.
- 메타데이터 시작을 클릭합니다.
KitchenSink는 NAVIGATION 포커스를 요청합니다. 이 포커스는 DirectRenderingCluster
서비스가 Instrument Cluster에서 모의 사용자 인터페이스를 표시하도록 지시합니다.