Instrument Cluster API

Google Haritalar da dahil olmak üzere navigasyon uygulamalarını bir araçtaki ikincil ekranda (ör. gösterge panelindeki direksiyonun arkasında) göstermek için Instrument Cluster API'yi (bir Android API'si) kullanın. Bu sayfada, ikincil ekranı kontrol etmek için bir hizmetin nasıl oluşturulacağı ve hizmetin CarService ile nasıl entegre edileceği açıklanmaktadır. Böylece, gezinme uygulamaları bir kullanıcı arayüzü gösterebilir.

Terminoloji

Bu sayfada aşağıdaki terimler kullanılmaktadır.

CarInstrumentClusterManager
Harici uygulamaların gösterge grubunda etkinlik başlatmasına ve gösterge grubu etkinlikleri göstermeye hazır olduğunda geri aramalar almasına olanak tanıyan bir CarManager örneği.
CarManager
Harici uygulamaların CarService tarafından uygulanan arabaya özel hizmetlerle etkileşim kurmak için kullandığı tüm yöneticilerin temel sınıfı.
CarService
Google Haritalar dahil olmak üzere harici uygulamalar ile gösterge paneli erişimi gibi araca özgü özellikler arasında iletişim sağlayan Android Platform hizmeti.
Hedef
Aracın gideceği nihai varış noktası.
Tahmini varış zamanı (TVZ)
Hedefe tahmini varış zamanı.
Ana birim (HU)
Araca yerleştirilmiş birincil hesaplama birimi. Baş ünite tüm Android kodunu çalıştırır ve arabadaki merkezi ekrana bağlıdır.
Gösterge grubu
Direksiyonun arkasında ve araba göstergelerinin arasında bulunan ikincil ekran. Bu, aracın dahili ağı (CAN veri yolu) üzerinden HU'ya bağlı bağımsız bir hesaplama birimi veya HU'ya bağlı ikincil bir ekran olabilir.
InstrumentClusterRenderingService
Gösterge paneli ekranıyla arayüz oluşturmak için kullanılan hizmetin temel sınıfı. OEM'ler, OEM'e özgü donanımla etkileşim kuran bu sınıfın bir uzantısını sağlamalıdır.
KitchenSink uygulaması
Android Automotive ile birlikte gelen test uygulaması.
Rota
Bir aracın hedefe ulaşmak için kullandığı belirli bir yol.
Singleton hizmeti
android:singleUser özelliği olan bir Android hizmeti. Herhangi bir zamanda Android sisteminde en fazla bir hizmet örneği çalışır.

Ön koşullar

Devam etmeden önce aşağıdaki öğelere sahip olduğunuzdan emin olun:

  • Android geliştirme ortamı. Android geliştirme ortamını ayarlamak için Derleme şartları bölümüne bakın.
  • Android kaynak kodunu indirin. https://android.googlesource.com adresindeki pi-car-release dalından (veya daha yeni bir daldan) Android kaynak kodunun en son sürümünü edinin.
  • Baş ünite (HU). Android 9 (veya sonraki sürümler) çalıştırabilen bir Android cihaz. Bu cihazın kendi ekranı olmalı ve ekranı Android'in yeni sürümleriyle güncelleyebilmelidir.
  • Gösterge grubu aşağıdakilerden biri olmalıdır:
    • HU'ya bağlı fiziksel ikincil ekran. Cihaz donanımı ve çekirdeği birden fazla ekranın yönetimini destekliyorsa.
    • Bağımsız birim: Bir ağ bağlantısı üzerinden HU'ya bağlı olan, video akışını kendi ekranında alıp görüntüleyebilen tüm hesaplama birimleri.
    • Emülasyonlu ekran. Geliştirme sırasında şu emüle edilmiş ortamlardan birini kullanabilirsiniz:
      • Simüle edilmiş ikincil ekranlar. Herhangi bir AOSP Android dağıtımında simüle edilmiş bir ikincil ekranı etkinleştirmek için Ayarlar sistem uygulamasındaki Geliştirici Seçenekleri'ne gidip İkincil ekranları simüle et'i seçin. Bu yapılandırma, fiziksel bir ikincil ekranı bağlamaya eşdeğerdir. Ancak bu ekran, birincil ekranın üzerine yerleştirilir.
      • Öykünülen gösterge paneli. AAOS'a dahil edilen Android emülatörü, ClusterRenderingService ile bir gösterge paneli görüntüleme seçeneği sunar.

Entegrasyon mimarisi

Entegrasyon bileşenleri

Gösterge Paneli API'sinin herhangi bir entegrasyonu şu üç bileşenden oluşur:

  • CarService
  • Navigasyon uygulamaları
  • OEM Gösterge Grubu Hizmeti

Entegrasyon bileşenleri

CarService

CarService, navigasyon uygulamaları ile araba arasında aracılık yaparak herhangi bir zamanda yalnızca bir navigasyon uygulamasının etkin olmasını ve yalnızca android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL iznine sahip uygulamaların arabaya veri gönderebilmesini sağlar.

CarService, arabaya özel tüm hizmetleri başlatır ve bir dizi yönetici aracılığıyla bu hizmetlere erişim sağlar. Hizmetlerle etkileşimde bulunmak için arabada çalışan uygulamalar bu yöneticilere erişebilir.

Gösterge paneli uygulaması için otomotiv OEM'leri, InstrumentClusterRendererService'in özel bir uygulamasını oluşturmalı ve ClusterRenderingService'i güncellemelidir.

Gösterge grubu oluşturulurken başlatma işlemi sırasında CarService, InstrumentClusterService uygulamasını bulmak için ClusterRenderingService'in InstrumentClusterRendererService anahtarını okur. AOSP'de bu giriş, Navigation State API örnek küme uygulaması oluşturma hizmetine işaret eder:

<string name="instrumentClusterRendererService">
android.car.cluster/.ClusterRenderingService
</string>

Bu girişte belirtilen hizmet başlatılır ve CarService'ya bağlanır. Google Haritalar gibi navigasyon uygulamaları CarInstrumentClusterManager istediğinde CarService, bağlı InstrumentClusterRenderingService'dan gösterge paneli durumunu güncelleyen bir yönetici sağlar. (Bu durumda bağlı, Android Hizmetleri'ni ifade eder.)

Gösterge grubu hizmeti

OEM'ler, ClusterRenderingService sınıfının bir alt sınıfını içeren bir Android paketi (APK) oluşturmalıdır.

Bu sınıf iki amaca hizmet eder:

  • Android ile gösterge paneli oluşturma cihazı arasında arayüz sağlar (bu sayfanın amacı).
  • Adım adım rota yönlendirmesi gibi navigasyon durumu güncellemelerini alır ve oluşturur.

İlk amaç için, InstrumentClusterRendererService'nin OEM uygulamaları, araba kabinindeki ekranlarda bilgileri oluşturmak için kullanılan ikincil ekranı başlatmalı ve InstrumentClusterRendererService.setClusterActivityOptions() ile InstrumentClusterRendererService.setClusterActivityState() yöntemlerini çağırarak bu bilgileri CarService'ye iletmelidir.

İkinci işlev için Gösterge Paneli hizmeti, eventType olarak kodlanmış ve paket halinde kodlanmış etkinlik verileri olan navigasyon durumu güncelleme etkinliklerini alan ClusterRenderingService arayüzünün bir uygulamasını sağlamalıdır.

Entegrasyon sırası

Aşağıdaki diyagramda, güncellemeleri işleyen bir Gezinme durumunun uygulanması gösterilmektedir:

Entegrasyon sırası

Bu resimde renkler şunları ifade eder:

  • Sarı. CarService ve CarNavigationStatusManager Android platformu tarafından sağlanır. Daha fazla bilgi edinmek için Car ve CAR_NAVIGATION_SERVICE sayfalarını inceleyin.
  • Camgöbeği. InstrumentClusterRendererService, OEM tarafından uygulanır.
  • Mor Google ve üçüncü taraf geliştiriciler tarafından uygulanan Navigasyon uygulaması.
  • Yeşil. CarAppFocusManager. Daha fazla bilgi edinmek için aşağıdaki CarAppFocusManager API'yi kullanma bölümüne ve CarAppFocusManager sayfasına bakın.

Gezinme durumu bilgi akışı şu sırayı izler:

  1. CarService, InstrumentClusterRenderingService öğesini başlatır.
  2. Başlatma sırasında InstrumentClusterRenderingService, CarService ile güncellenir:
    1. Sınırları kapatmama gibi gösterge paneli görüntüleme özellikleri (Sınırları kapatmama hakkında daha fazla bilgiyi sonraki bölümlerde bulabilirsiniz).
    2. Gösterge grubu ekranında etkinlik başlatmak için gereken etkinlik seçenekleri. Daha fazla bilgi edinmek için ActivityOptions başlıklı makaleyi inceleyin.
  3. Bir navigasyon uygulaması (ör. Android Automotive için Google Haritalar veya gerekli izinlere sahip herhangi bir harita uygulaması):
    1. car-lib'deki Car sınıfını kullanarak CarAppFocusManager alır.
    2. Adım adım yol tarifi başlamadan önce, CarAppFocusManager.requestFocus() numarasına yapılan aramalar, appType parametresi olarak CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION değerini iletir.
  4. CarAppFocusManager bu isteği CarService iletir. İzin verilirse CarService, gezinme uygulaması paketini inceler ve android.car.cluster.NAVIGATION kategorisiyle işaretlenmiş bir etkinlik bulur.
  5. Bulunursa gezinme uygulaması, etkinliği başlatmak için ActivityOptions tarafından bildirilen InstrumentClusterRenderingService kullanır ve gösterge paneli görüntüleme özelliklerini amaçta ekstralar olarak içerir.

API'yi entegre etme

InstrumentClusterRenderingService uygulaması şu özelliklere sahip olmalıdır:

  • AndroidManifest.xml dosyasına aşağıdaki değeri ekleyerek tek örnekli hizmet olarak belirlenmelidir. Bu, başlatma ve kullanıcı değiştirme sırasında bile Instrument Cluster hizmetinin tek bir kopyasının çalışmasını sağlamak için gereklidir:
    android:singleUser="true"
  • BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE sistem iznini tutun. Bu, CarService tarafından yalnızca Android sistem görüntüsünün bir parçası olarak dahil edilen gösterge paneli oluşturma hizmetinin bağlanmasını sağlar:
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

InstrumentClusterRenderingService'i uygulama

Hizmeti oluşturmak için:

  1. ClusterRenderingService'ten türeyen bir sınıf yazın ve ardından AndroidManifest.xml dosyanıza ilgili bir giriş ekleyin. Bu sınıf, gösterge paneli ekranını kontrol eder ve (isteğe bağlı olarak) Navigation State API verilerini oluşturabilir.
  2. onCreate() sırasında, oluşturma donanımıyla iletişimi başlatmak için bu hizmeti kullanın. Seçenekler şunlardır:
    • Gösterge paneli için kullanılacak ikincil ekranı belirleyin.
    • Gösterge Paneli uygulamasının oluşturulan görüntüyü oluşturup harici bir birime (H.264 gibi bir video akışı biçimi kullanarak) iletmesi için sanal bir ekran oluşturun.
  3. Yukarıda belirtilen ekran hazır olduğunda bu hizmet, InstrumentClusterRenderingService#setClusterActivityLaunchOptions() çağrısı yaparak Etkinliklerin gösterge panelinde gösterilmesi için kullanılması gereken tam ActivityOptions değerini tanımlamalıdır. Şu parametreleri kullanın:
    • category. ClusterRenderingService.
    • ActivityOptions. Gösterge grubunda bir etkinliği başlatmak için kullanılabilecek bir ActivityOptions örneği. Örneğin, AOSP'deki örnek gösterge grubu uygulamasından:
      getService().setClusterActivityLaunchOptions(
        CATEGORY_NAVIGATION,
        ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
  4. Gösterge paneli etkinlikleri göstermeye hazır olduğunda bu hizmet InstrumentClusterRenderingService#setClusterActivityState() işlevini çağırmalıdır. Şu parametreleri kullanın:
    • category ClusterRenderingService.
    • state ClusterRenderingService ile oluşturulan paket. Aşağıdaki verileri sağladığınızdan emin olun:
      • visible Gösterge panelinin görünür ve içerik göstermeye hazır olduğunu belirtir.
      • unobscuredBounds İçeriklerin güvenli bir şekilde gösterilebileceği, gösterge paneli ekranındaki alanı tanımlayan bir dikdörtgen. Örneğin, kadranlar ve göstergelerle kaplı alanlar.
  5. Service#dump() yöntemini geçersiz kılın ve hata ayıklama için yararlı olan durum bilgilerini bildirin (daha fazla bilgi için dumpsys bölümüne bakın).

Örnek InstrumentClusterRenderingService uygulaması

Aşağıdaki örnekte, InstrumentCluster içeriğini uzak bir fiziksel ekranda sunmak için InstrumentClusterRenderingService oluşturulan bir VirtualDisplay uygulaması özetlenmektedir.

Alternatif olarak, bu kod, HU'ya bağlı fiziksel bir ikincil ekranın displayId değerini de iletebilir (varsa).

/**
* 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'yi kullanma

CarAppFocusManager API'si, getAppTypeOwner() adlı bir yöntem sağlar. Bu yöntem, OEM'ler tarafından yazılan küme hizmetinin, herhangi bir zamanda hangi navigasyon uygulamasının gezinme odağına sahip olduğunu bilmesini sağlar. OEM'ler mevcut CarAppFocusManager#addFocusListener() yöntemini kullanabilir ve ardından hangi uygulamanın odaklandığını öğrenmek için getAppTypeOwner() yöntemini kullanabilir. Bu bilgilerle OEM'ler:

  • Kümede gösterilen etkinliği, odaklanılan navigasyon uygulaması tarafından sağlanan küme etkinliğiyle değiştirin.
  • Odaklanılan navigasyon uygulamasında küme etkinliği olup olmadığını algılayabilir. Odaklanılan navigasyon uygulamasında küme etkinliği yoksa (veya bu etkinlik devre dışıysa) OEM'ler bu sinyali arabanın DIM'ine gönderebilir. Böylece kümenin navigasyon yönü tamamen atlanır.

CarAppFocusManager tuşunu kullanarak etkin gezinme veya sesli komut gibi mevcut uygulama odağını ayarlayın ve dinleyin. Genellikle bu tür bir uygulamanın yalnızca bir örneği sistemde etkin olarak çalışır (veya odaklanır).

Uygulama odağı değişikliklerini dinlemek için CarAppFocusManager#addFocusListener(..) yöntemini kullanın:

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
}

Odaklanılan belirli bir uygulama türünün mevcut sahibinin paket adlarını almak için CarAppFocusManager#getAppTypeOwner(..) yöntemini kullanın. Mevcut sahip android:sharedUserId özelliğini kullanıyorsa bu yöntem birden fazla paket adı döndürebilir.

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
}

...

Şablon uygulamaları tanımlama

Car App kitaplığını kullanan şablona dayalı gezinme uygulamaları için, CarAppFocusManager#getAppTypeOwner(), istemci uygulama adına sistem odağını ana makine tuttuğu için ana makinenin paket adını (ör. com.google.android.apps.automotive.templates.host) döndürür.

OEM'ler, gezinme yapan istemci uygulamasını tanımlamak için CarNavigationStatusManager ile gönderilen gezinme durumu paketinden paket adını çıkarabilir. Paket adı, NavigationRenderer#onNavigationStateChanged(Bundle) tarafından alınan paketteki active_app_package_name anahtarı altında saklanır:

// In your NavigationRenderer implementation
@Override
public void onNavigationStateChanged(Bundle bundle) {
    if (bundle.containsKey("active_app_package_name")) {
        String activeAppPackage = bundle.getString("active_app_package_name");
        // Use the package name to identify the navigating app (e.g., com.waze)
    }
}

Ek: Örnek uygulamayı kullanma

AOSP, Navigation State API'yi uygulayan bir örnek uygulama sağlar.

Bu örnek uygulamayı çalıştırmak için:

  1. Desteklenen bir ana birimde Android Auto'yu oluşturup yükleyin. Cihazınıza özel Android derleme ve yükleme talimatlarını kullanın. Talimatlar için Referans panolarını kullanma başlıklı makaleyi inceleyin.
  2. Fiziksel bir ikincil ekranı HU'ya bağlayın (destekleniyorsa) veya sanal ikincil HU'yu açın:
    1. Ayarlar uygulamasında Geliştirici Modu'nu seçin.
    2. Ayarlar > Sistem > Gelişmiş > Geliştirici seçenekleri > İkincil ekranları simüle et'e gidin.
  3. HU'yu yeniden başlatın
  4. KitchenSink uygulamasını başlatmak için:
    1. Çekmeceyi açın.
    2. Inst. Cluster'a (Kurulu Küme) gidin.
    3. META VERİLERİ BAŞLAT'ı tıklayın.

KitchenSink, NAVIGATION odaklanma isteğinde bulunur. Bu istek, DirectRenderingCluster hizmetine gösterge panelinde sahte bir kullanıcı arayüzü göstermesi talimatını verir.