Instrument Cluster API

Instrument Cluster API(Android API)를 사용하여 Google 지도를 포함한 내비게이션 앱을 자동차의 보조 디스플레이(예: 핸들 뒤의 계기판)에 표시합니다. 이 페이지에서는 이를 통해 보조 디스플레이를 제어하고 CarService - 내비게이션 앱에서 구성할 수 있습니다.

용어

이 페이지에서 사용되는 용어는 다음과 같습니다.

CarInstrumentClusterManager
외부 앱이 다음에서 활동을 시작할 수 있도록 하는 CarManager의 인스턴스입니다. Instrument Cluster로 연결되고 Instrument Cluster가 표시할 준비가 되면 콜백을 수신합니다. 있습니다.
CarManager
외부 앱이 자동차 관련 앱과 상호작용하는 데 사용하는 모든 관리자의 기본 클래스 CarService로 구현되는 서비스입니다.
CarService
외부 앱 간의 통신을 제공하는 Android 플랫폼 서비스 (Google 지도 포함) 및 Instrument Cluster 액세스와 같은 자동차 관련 기능
목적지
차량이 이동할 최종 목적지입니다.
예상 도착 시간 (ETA)
목적지 도착 예정 시간입니다.
헤드 단위(HU)
자동차에 내장된 기본 전산 단위입니다. HU는 모든 Android 코드를 실행하며 자동차의 중앙 디스플레이에 연결되어 있습니다.
Instrument Cluster
핸들 뒤 자동차 사이에 위치한 보조 디스플레이 배우게 됩니다. 이는 자동차의 내부 네트워크(CAN 버스)를 통해 HU에 연결된 독립적인 전산 단위이거나 HU에 연결된 보조 디스플레이일 수 있습니다.
InstrumentClusterRenderingService
Instrument Cluster와 상호작용하는 데 사용되는 서비스의 기본 클래스입니다. 디스플레이. OEM은 OEM별 하드웨어와 상호작용하는 이 클래스의 확장 프로그램을 제공해야 합니다.
KitchenSink 앱
Android Automotive에 포함된 테스트 앱입니다.
경로
차량이 목적지에 도착하기 위해 이동하는 특정 경로입니다.
싱글톤 서비스
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 플랫폼에서 제공하는 CarServiceCarNavigationStatusManager입니다. 자세한 내용은 자동차CAR_NAVIGATION_SERVICE를 참고하세요.
  • 녹청색. OEM에서 구현하는 InstrumentClusterRendererService입니다.
  • 자주색. Google 및 서드 파티 개발자가 구현하는 네비게이션 앱입니다.
  • 녹색. CarAppFocusManager입니다. 자세한 내용은 아래의 CarAppFocusManager API 사용CarAppFocusManager를 참고하세요.

탐색 상태 정보 흐름은 다음 시퀀스를 따릅니다.

  1. CarServiceInstrumentClusterRenderingService를 초기화합니다.
  2. 초기화 중에 InstrumentClusterRenderingServiceCarService를 다음으로 업데이트합니다.
    1. 뚜렷한 경계와 같은 Instrument Cluster 디스플레이 속성입니다(나중에 뚜렷한 경계에 관한 자세한 내용 참고).
    2. Instrument Cluster 디스플레이 내에서 활동을 시작하는 데 필요한 활동 옵션입니다. 자세한 내용은 ActivityOptions에서 사용할 수 있습니다.
  3. 내비게이션 앱 (예: Android Automotive용 Google 지도 또는 모든 지도 앱) 권한이 있는 사용자)에 액세스할 수 있습니다. <ph type="x-smartling-placeholder">
      </ph>
    1. car-lib에서 Car 클래스를 사용하여 CarAppFocusManager를 가져옵니다.
    2. 세부 경로 안내가 시작되기 전에 통과까지 CarAppFocusManager.requestFocus() 남음 appType(으)로 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION 매개변수 값으로 사용됩니다.
  4. CarAppFocusManager가 이 요청을 CarService에 전달합니다. 권한이 부여된 경우 CarService는 내비게이션 앱 패키지를 검사하고 android.car.cluster.NAVIGATION 카테고리로 표시된 활동을 찾습니다.
  5. 찾은 경우 내비게이션 앱은 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 구현

서비스를 빌드하려면:

  1. 다음에서 확장되는 클래스 작성 ClusterRenderingService(클러스터 렌더링 서비스) 그런 다음 상응하는 항목을 AndroidManifest.xml 파일에 추가합니다. 이 수업 계기판 디스플레이를 제어하고 (필요한 경우) 내비게이션 상태를 렌더링할 수 있습니다. API 데이터입니다.
  2. onCreate() 중에 이 서비스를 사용하여 사용할 수 있습니다. 다음과 같은 옵션이 있습니다.
    • Instrument Cluster에 사용할 보조 디스플레이를 결정합니다.
    • Instrument Cluster 앱이 다음을 렌더링하고 전송하도록 가상 디스플레이를 만듭니다. 이미지를 외부 장치에 보냅니다 (H.264 등의 동영상 스트리밍 형식 사용).
  3. 위에 표시된 디스플레이가 준비되면 이 서비스는 InstrumentClusterRenderingService#setClusterActivityLaunchOptions()를 호출하여 Instrument Cluster에서 활동을 표시하는 데 사용해야 하는 정확한 ActivityOptions를 정의해야 합니다. 다음 매개변수를 사용합니다.
    • category. ClusterRenderingService입니다.
    • ActivityOptions. Instrument Cluster에서 활동을 시작하는 데 사용할 수 있는 ActivityOptions 인스턴스입니다. 예를 들어 AOSP의 샘플 Instrument Cluster 구현에서 시작합니다.
      getService().setClusterActivityLaunchOptions(
        CATEGORY_NAVIGATION,
        ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
  4. Instrument Cluster가 활동을 표시할 준비가 되면 이 서비스는 InstrumentClusterRenderingService#setClusterActivityState()를 호출해야 합니다. 다음 매개변수를 사용합니다.
    • category ClusterRenderingService입니다.
    • 다음으로 생성된 번들 stateClusterRenderingService입니다. 다음 데이터를 제공해야 합니다. <ph type="x-smartling-placeholder">
        </ph>
      • visible Instrument Cluster를 공개 가능 및 콘텐츠 표시 가능으로 지정합니다.
      • unobscuredBounds 콘텐츠를 안전하게 표시할 수 있는 Instrument Cluster 디스플레이 내 영역을 정의하는 직사각형입니다. 다이얼 및 게이지가 적용되는 영역을 예로 들 수 있습니다.
  5. 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를 구현하는 샘플 앱을 제공합니다.

이 샘플 앱을 실행하는 방법은 다음과 같습니다.

  1. 지원되는 HU에서 Android Auto를 빌드하고 플래시합니다. 사용 중인 기기와 관련된 Android 빌드 및 플래시 안내를 사용합니다. 자세한 내용은 참조 보드 사용을 참고하세요.
  2. 물리적 보조 디스플레이를 HU (지원되는 경우)에 연결하거나 가상 디스플레이를 켭니다. 보조 HU: <ph type="x-smartling-placeholder">
      </ph>
    1. 설정 앱에서 개발자 모드를 선택합니다.
    2. 설정 > 시스템 > 고급 > 개발자 옵션 > 보조 디스플레이 시뮬레이션하기
  3. HU 재부팅
  4. KitchenSink 앱을 실행하려면 다음 단계를 따르세요.
    1. 창을 엽니다.
    2. Instrument Cluster로 이동합니다.
    3. 메타데이터 시작을 클릭합니다.

KitchenSink는 NAVIGATION 포커스를 요청합니다. 이 포커스는 DirectRenderingCluster 서비스가 Instrument Cluster에서 모의 사용자 인터페이스를 표시하도록 지시합니다.