Instrument Cluster API

از Instrument Cluster API (یک API Android) برای نمایش برنامه‌های ناوبری، از جمله Google Maps، بر روی یک صفحه نمایش ثانویه در خودرو، مانند پشت فرمان روی پانل ابزار، استفاده کنید. این صفحه نحوه ایجاد سرویسی برای کنترل نمایشگر ثانویه و ادغام سرویس با CarService را توضیح می دهد تا برنامه های ناوبری بتوانند یک رابط کاربری را نمایش دهند.

اصطلاحات

در این صفحه از اصطلاحات زیر استفاده می شود.

CarInstrumentClusterManager
نمونه‌ای از CarManager که برنامه‌های خارجی را قادر می‌سازد تا فعالیتی را در Instrument Cluster راه‌اندازی کنند و زمانی که Instrument Cluster آماده نمایش فعالیت‌ها است، تماس‌های برگشتی دریافت کنند.
مدیر خودرو
کلاس پایه از همه مدیرانی که توسط برنامه‌های خارجی برای تعامل با سرویس‌های مخصوص خودرو اجرا شده توسط CarService استفاده می‌شوند.
CarService
سرویس پلتفرم Android که ارتباط بین برنامه‌های خارجی (از جمله Google Maps) و ویژگی‌های خاص خودرو، مانند دسترسی به Instrument Cluster را فراهم می‌کند.
مقصد
مقصد نهایی که وسیله نقلیه به سمت آن حرکت خواهد کرد.
زمان تخمینی ورود (ETA)
زمان تخمینی رسیدن به مقصد.
واحد مرکزی (HU)
واحد محاسباتی اولیه تعبیه شده در خودرو HU تمامی کدهای اندروید را اجرا می کند و به نمایشگر مرکزی خودرو متصل می شود.
خوشه ابزار
نمایشگر ثانویه که در پشت فرمان و بین ابزار ماشین قرار دارد. این می تواند یک واحد محاسباتی مستقل باشد که از طریق شبکه داخلی خودرو (گذرگاه CAN) به HU متصل است یا یک نمایشگر ثانویه متصل به HU.
InstrumentClusterRenderingService
کلاس پایه برای سرویس مورد استفاده برای ارتباط با نمایشگر Instrument Cluster. OEM ها باید افزونه ای از این کلاس را ارائه دهند که با سخت افزار خاص OEM تعامل داشته باشد.
اپلیکیشن KitchenSink
برنامه آزمایشی همراه با Android Automotive.
مسیر
مسیر مشخصی که در آن وسیله نقلیه برای رسیدن به مقصد حرکت می کند.
سرویس سینگلتون
یک سرویس اندروید با ویژگی android:singleUser . در هر زمان، حداکثر یک نمونه از این سرویس در سیستم اندروید اجرا می شود.

پیش نیازها

قبل از ادامه، حتما این عناصر را داشته باشید:

  • محیط توسعه اندروید. برای راه‌اندازی محیط توسعه Android، نیازمندی‌های ساخت را ببینید.
  • کد منبع اندروید را دانلود کنید. آخرین نسخه کد منبع Android را از شعبه pi-car-release (یا جدیدتر) در https://android.googlesource.com دریافت کنید.
  • واحد سر (HU). یک دستگاه اندرویدی که قابلیت اجرای اندروید 9 (یا جدیدتر) را دارد. این دستگاه باید نمایشگر مخصوص به خود را داشته باشد و قابلیت فلش نمایشگر با بیلدهای جدید اندروید را داشته باشد.
  • Instrument Cluster یکی از موارد زیر است:
    • نمایشگر ثانویه فیزیکی متصل به HU. اگر سخت افزار و هسته دستگاه از مدیریت نمایشگرهای متعدد پشتیبانی می کند.
    • واحد مستقل هر واحد محاسباتی متصل به HU از طریق اتصال شبکه، که قادر به دریافت و نمایش یک جریان ویدیویی بر روی نمایشگر خود است.
    • نمایشگر شبیه سازی شده در طول توسعه، می توانید از یکی از این محیط های شبیه سازی شده استفاده کنید:
      • نمایشگرهای ثانویه شبیه سازی شده برای فعال کردن یک نمایشگر ثانویه شبیه سازی شده در هر توزیع AOSP Android، به تنظیمات Developer Options در برنامه تنظیمات سیستم بروید و سپس Simulate secondary displays را انتخاب کنید. صفحه نمایش اولیه
      • خوشه ابزار شبیه سازی شده شبیه ساز اندروید همراه با AAOS گزینه ای برای نمایش یک خوشه ابزار با ClusterRenderingService فراهم می کند.

معماری یکپارچه سازی

اجزای یکپارچه سازی

هر ادغام Instrument Cluster API از این سه جزء تشکیل شده است:

  • CarService
  • برنامه های ناوبری
  • خدمات خوشه ابزار OEM

اجزای یکپارچه سازی

CarService

CarService بین برنامه‌های ناوبری و خودرو میانجیگری می‌کند و اطمینان می‌دهد که در هر زمان فقط یک برنامه ناوبری فعال است و فقط برنامه‌های دارای مجوز android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL می‌توانند داده‌ها را به خودرو ارسال کنند.

CarService تمام خدمات مخصوص خودرو را بوت استرپ می کند و از طریق یک سری مدیران امکان دسترسی به این خدمات را فراهم می کند. برای تعامل با سرویس‌ها، برنامه‌های در حال اجرا در خودرو می‌توانند به این مدیران دسترسی داشته باشند.

برای پیاده سازی خوشه ابزار، OEM های خودرو باید یک پیاده سازی سفارشی از InstrumentClusterRendererService ایجاد کنند و ClusterRenderingService را به روز کنند.

هنگام رندر کردن یک Instrument Cluster، در طول فرآیند بوت، CarService کلید InstrumentClusterRendererService ClusterRenderingService را می خواند تا پیاده سازی InstrumentClusterService را پیدا کند. در AOSP، این ورودی به سرویس رندر اجرای خوشه نمونه API وضعیت ناوبری اشاره می کند:

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

سرویس اشاره شده در این ورودی مقداردهی اولیه شده و به CarService محدود شده است. وقتی برنامه‌های ناوبری، مانند Google Maps، CarInstrumentClusterManager درخواست می‌کنند، CarService مدیری را ارائه می‌کند که وضعیت Instrument Cluster را از InstrumentClusterRenderingService محدود شده به‌روزرسانی می‌کند. (در این مورد، bound به خدمات Android اشاره دارد.)

سرویس کلاستر ابزار

OEM ها باید یک بسته Android (APK) ایجاد کنند که حاوی زیرکلاس ClusterRenderingService باشد.

این کلاس دو هدف را دنبال می کند:

  • یک رابط اندروید و دستگاه رندر Instrument Cluster (هدف این صفحه) را ارائه می دهد.
  • به‌روزرسانی‌های وضعیت ناوبری، مانند راهنمای ناوبری گام به گام را دریافت و ارائه می‌کند.

برای اولین هدف، پیاده‌سازی‌های OEM InstrumentClusterRendererService باید نمایشگر ثانویه مورد استفاده برای CarService کردن اطلاعات روی صفحه‌های کابین خودرو را راه‌اندازی کنند و این اطلاعات را با فراخوانی به روش‌های InstrumentClusterRendererService.setClusterActivityOptions() و InstrumentClusterRendererService.setClusterActivityState() .

برای عملکرد دوم، سرویس Instrument Cluster باید پیاده سازی ClusterRenderingService را ارائه دهد. رابطی که رویدادهای به‌روزرسانی وضعیت ناوبری را دریافت می‌کند، که به‌عنوان eventType و داده‌های رویداد در یک بسته کدگذاری می‌شوند.

دنباله ادغام

نمودار زیر اجرای یک حالت ناوبری را نشان می دهد که به روز رسانی ها را ارائه می دهد:

دنباله ادغام

در این تصویر، رنگ ها به موارد زیر اشاره می کنند:

  • زرد. CarService و CarNavigationStatusManager ارائه شده توسط پلتفرم اندروید. برای کسب اطلاعات بیشتر، به خودرو و CAR_NAVIGATION_SERVICE مراجعه کنید.
  • فیروزه ای. InstrumentClusterRendererService توسط OEM پیاده سازی شده است.
  • بنفش. برنامه ناوبری که توسط گوگل و توسعه دهندگان شخص ثالث پیاده سازی شده است.
  • سبز. CarAppFocusManager . برای کسب اطلاعات بیشتر، به استفاده از CarAppFocusManager API زیر و CarAppFocusManager مراجعه کنید.

جریان اطلاعات وضعیت ناوبری از این ترتیب پیروی می کند:

  1. CarService InstrumentClusterRenderingService را مقداردهی اولیه می کند.
  2. در طول مقداردهی اولیه، InstrumentClusterRenderingService CarService با موارد زیر به روز می کند:
    1. ویژگی های نمایش خوشه ابزار، مانند مرزهای مبهم (جزئیات بیشتر در مورد مرزهای مبهم را در ادامه ببینید).
    2. گزینه‌های فعالیت برای راه‌اندازی فعالیت‌ها در داخل نمایشگر Instrument Cluster مورد نیاز است. برای کسب اطلاعات بیشتر، به ActivityOptions مراجعه کنید.
  3. یک برنامه ناوبری (مانند Google Maps برای Android Automotive یا هر برنامه نقشه با مجوزهای لازم):
    1. یک CarAppFocusManager با استفاده از کلاس Car از car-lib به دست می آورد.
    2. قبل از شروع مسیرهای گام به گام، CarAppFocusManager.requestFocus() را فراخوانی می کند تا CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION را به عنوان پارامتر appType ارسال کند.
  4. CarAppFocusManager این درخواست را به CarService ارسال می کند. در صورت اعطای مجوز، CarService بسته برنامه پیمایش را بررسی می‌کند و فعالیتی را که با دسته android.car.cluster.NAVIGATION مشخص شده است، پیدا می‌کند.
  5. اگر پیدا شد، برنامه ناوبری از ActivityOptions گزارش شده توسط InstrumentClusterRenderingService برای راه اندازی فعالیت استفاده می کند و ویژگی های نمایشگر Instrument Cluster را به عنوان موارد اضافی در intent شامل می شود.

API را یکپارچه کنید

اجرای InstrumentClusterRenderingService باید:

  • با افزودن مقدار زیر به AndroidManifest.xml، به عنوان یک سرویس singleton تعیین شود. این برای اطمینان از اجرای یک کپی از سرویس Instrument Cluster ضروری است، حتی در هنگام راه اندازی اولیه و تعویض کاربر:
    android:singleUser="true"
  • مجوز سیستم BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE را نگه دارید. این تضمین می‌کند که فقط سرویس ارائه خوشه ابزار که به عنوان بخشی از تصویر سیستم اندروید است، توسط CarService محدود می‌شود:
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

InstrumentClusterRenderingService را پیاده سازی کنید

برای ساخت سرویس:

  1. کلاسی بنویسید که از ClusterRenderingService گسترش یابد و سپس ورودی مربوطه را به فایل AndroidManifest.xml خود اضافه کنید. این کلاس نمایشگر Instrument Cluster را کنترل می کند و می تواند ( به صورت اختیاری ) داده های Navigation State API را ارائه کند.
  2. در طول onCreate() از این سرویس برای مقداردهی اولیه ارتباط با سخت افزار رندر استفاده کنید. گزینه ها عبارتند از:
    • نمایشگر ثانویه مورد استفاده برای Instrument Cluster را تعیین کنید.
    • یک نمایشگر مجازی ایجاد کنید تا برنامه Instrument Cluster تصویر رندر شده را رندر کند و به یک واحد خارجی (با استفاده از فرمت پخش ویدئو، مانند H.264) منتقل کند.
  3. وقتی صفحه نمایش نشان داده شده در بالا آماده است، این سرویس باید InstrumentClusterRenderingService#setClusterActivityLaunchOptions() را فراخوانی کند تا ActivityOptions دقیقی را که باید برای نمایش یک Activity در Instrument Cluster استفاده شود، تعریف کند. از این پارامترها استفاده کنید:
    • category. ClusterRenderingService .
    • ActivityOptions. یک نمونه ActivityOptions که می تواند برای راه اندازی یک Activity در Instrument Cluster استفاده شود. به عنوان مثال، از نمونه پیاده سازی Instrument Cluster در AOSP:
      getService().setClusterActivityLaunchOptions(
        CATEGORY_NAVIGATION,
        ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
  4. هنگامی که Instrument Cluster آماده نمایش فعالیت ها است، این سرویس باید InstrumentClusterRenderingService#setClusterActivityState() را فراخوانی کند. از این پارامترها استفاده کنید:
    • category ClusterRenderingService .
    • state Bundle با ClusterRenderingService ایجاد شد. حتما این داده ها را ارائه دهید:
      • visible خوشه ابزار را به عنوان قابل مشاهده و آماده برای نمایش محتوا مشخص می کند.
      • unobscuredBounds مستطیلی است که ناحیه ای را در نمایشگر Instrument Cluster تعریف می کند که در آن نمایش محتوا امن است. به عنوان مثال، مناطقی که توسط صفحه و گیج پوشانده شده است.
  5. روش Service#dump() را لغو کنید و اطلاعات وضعیت مفید برای اشکال زدایی را گزارش کنید (برای اطلاعات بیشتر به dumpsys مراجعه کنید).

نمونه اجرای InstrumentClusterRenderingService

مثال زیر یک پیاده سازی InstrumentClusterRenderingService را نشان می دهد که یک VirtualDisplay ایجاد می کند تا محتوای Instrument Cluster را بر روی یک نمایشگر فیزیکی از راه دور ارائه کند.

از طرف دیگر، این کد می‌تواند از displayId یک نمایشگر ثانویه فیزیکی متصل به HU، در صورتی که یکی از آن‌ها در دسترس است، عبور دهد.

/**
* 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 یک برنامه نمونه ارائه می دهد که API وضعیت ناوبری را پیاده سازی می کند.

برای اجرای این نمونه برنامه:

  1. Android Auto را روی HU پشتیبانی شده بسازید و فلش کنید. از دستورالعمل های ساختمان و فلش اندروید مخصوص دستگاه خود استفاده کنید. برای دستورالعمل ها، به استفاده از تابلوهای مرجع مراجعه کنید.
  2. یک نمایشگر ثانویه فیزیکی را به HU (در صورت پشتیبانی) وصل کنید یا HU ثانویه مجازی را روشن کنید:
    1. حالت برنامه‌نویس را در برنامه تنظیمات انتخاب کنید.
    2. به تنظیمات > سیستم > پیشرفته > گزینه های برنامه نویس > شبیه سازی نمایشگرهای ثانویه بروید.
  3. HU را مجددا راه اندازی کنید
  4. برای راه اندازی برنامه KitchenSink:
    1. کشو را باز کنید.
    2. به Inst بروید. خوشه .
    3. روی START METADATA کلیک کنید.

KitchenSink فوکوس NAVIGATION را درخواست می‌کند، که به سرویس DirectRenderingCluster دستور می‌دهد تا یک رابط کاربری ساختگی روی Instrument Cluster نمایش دهد.