واجهة برمجة تطبيقات مجموعة الأدوات

استخدم Instrument Cluster API (واجهة برمجة تطبيقات Android) لعرض تطبيقات الملاحة، بما في ذلك خرائط Google، على شاشة عرض ثانوية في السيارة، مثل خلف عجلة القيادة على لوحة العدادات. توضح هذه الصفحة كيفية إنشاء خدمة للتحكم في شاشة العرض الثانوية ثم دمج الخدمة مع CarService حتى تتمكن تطبيقات التنقل من عرض واجهة المستخدم.

المصطلح

يتم استخدام المصطلحات التالية في هذه الصفحة:

شرط وصف
CarInstrumentClusterManager مثيل CarManager الذي يمكّن التطبيقات الخارجية من إطلاق نشاط على مجموعة الأجهزة وتلقي عمليات الاسترجاعات عندما تكون مجموعة الأجهزة جاهزة لعرض الأنشطة.
CarManager الفئة الأساسية لجميع المديرين الذين تستخدمهم التطبيقات الخارجية للتفاعل مع الخدمات الخاصة بالسيارة التي تنفذها CarService .
CarService خدمة Android Platform التي توفر الاتصال بين التطبيقات الخارجية (بما في ذلك خرائط Google) والميزات الخاصة بالسيارة، مثل الوصول إلى مجموعة الأدوات.
وجهة الوجهة النهائية التي ستنتقل إليها المركبة.
الوقت المتوقع للوصول الوقت المقدر للوصول إلى الوجهة.
الوحدة الرئيسية (هو) وحدة حسابية أساسية مدمجة في السيارة. يقوم HU بتشغيل جميع أكواد Android وهو متصل بالشاشة المركزية في السيارة.
مجموعة الأدوات شاشة ثانوية تقع خلف عجلة القيادة وبين أدوات السيارة. يمكن أن تكون هذه وحدة حسابية مستقلة متصلة بوحدة HU من خلال الشبكة الداخلية للسيارة (ناقل CAN) أو شاشة ثانوية متصلة بوحدة HU.
InstrumentClusterRenderingService الفئة الأساسية للخدمة المستخدمة للتفاعل مع شاشة عرض مجموعة العدادات. يجب أن توفر الشركات المصنعة للمعدات الأصلية (OEM) امتدادًا لهذه الفئة التي تتفاعل مع الأجهزة الخاصة بـ OEM.
تطبيق كيتشن سينك تطبيق اختباري مضمن مع Android Automotive.
طريق مسار محدد تتنقل عبره المركبة للوصول إلى الوجهة.
خدمة سينجلتون خدمة Android مع السمة android:singleUser . في أي وقت، يتم تشغيل مثيل واحد على الأكثر من الخدمة على نظام Android.

المتطلبات الأساسية

لتطوير التكامل، تأكد من توفر هذه العناصر:

  • بيئة تطوير أندرويد. لإعداد بيئة تطوير Android، راجع متطلبات البناء .
  • قم بتنزيل كود مصدر Android. احصل على أحدث إصدار من كود مصدر Android من فرع إصدار pi-car (أو الأحدث) على https://android.googlesource.com .
  • الوحدة الرئيسية (HU). جهاز Android قادر على تشغيل Android 9 (أو الأحدث). يجب أن يكون لهذا الجهاز شاشة عرض خاصة به وأن يكون قادرًا على وميض الشاشة بإصدارات جديدة من Android.
  • مجموعة الأدوات هي واحدة مما يلي:
    • العرض الثانوي المادي المرفق بوحدة HU. إذا كانت أجهزة الجهاز والنواة تدعم إدارة شاشات متعددة.
    • وحدة مستقلة. أي وحدة حسابية متصلة بوحدة HU عبر اتصال شبكة، قادرة على استقبال وعرض دفق الفيديو على شاشتها الخاصة.
    • عرض مقلد. أثناء التطوير، يمكنك استخدام إحدى هذه البيئات التي تمت محاكاتها:
      • محاكاة يعرض الثانوية. لتمكين عرض ثانوي محاكى على أي توزيع AOSP Android، انتقل إلى إعدادات خيارات المطور في تطبيق نظام الإعدادات ثم حدد محاكاة شاشات العرض الثانوية. ويعادل هذا التكوين توصيل شاشة عرض ثانوية فعلية، مع تقييد تركيب شاشة العرض هذه على شاشة العرض الأساسية.
      • مجموعة الأدوات التي تمت محاكاتها. يوفر محاكي Android المضمن مع Android Automotive خيارًا لعرض مجموعة الأدوات مع توصيل خدمة ClusterRenderingService بالشاشة الثانوية.
      • محاكي _qemu-الأنابيب . خدمة ClusterRenderingService متصلة بالشاشة الثانوية. تنفيذ مجموعة الأدوات المرجعية للاتصال بهذه الشاشة الخارجية التي تمت محاكاتها.

بنية التكامل

مكونات التكامل

يتكون أي تكامل لـ Instrument Cluster API من هذه المكونات الثلاثة:

  • CarService
  • تطبيقات الملاحة
  • خدمة مجموعة أدوات OEM

مكونات التكامل

خدمة السيارات

تتوسط CarService بين تطبيقات الملاحة والسيارة، مما يضمن أن يكون هناك تطبيق تنقل واحد فقط نشط في أي وقت وأن التطبيقات التي لديها إذن android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL هي فقط التي يمكنها إرسال البيانات إلى السيارة.

تقوم CarService بتمهيد جميع الخدمات الخاصة بالسيارات وتوفر الوصول إلى هذه الخدمات من خلال سلسلة من المديرين. للتفاعل مع الخدمات، يمكن للتطبيقات التي تعمل في السيارة الوصول إلى هؤلاء المديرين.

لتنفيذ مجموعة الأدوات، يجب على مصنعي المعدات الأصلية للسيارات إنشاء تطبيق مخصص لـ InstrumentClusterRendererService وتحديث خدمة ClusterRenderingService المتصلة بالشاشة الثانوية.

عند عرض مجموعة الآلات، أثناء عملية التمهيد، تقرأ CarService مفتاح InstrumentClusterRendererService الخاص بخدمة ClusterRenderingService وهو متصل بشاشة العرض الثانوية. لتحديد موقع تطبيق InstrumentClusterService . في AOSP، يشير هذا الإدخال إلى خدمة عرض تطبيق مجموعة نموذج Navigation State API:

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

تتم تهيئة الخدمة المشار إليها في هذا الإدخال وربطها بـ CarService . عندما تطلب تطبيقات التنقل، مثل خرائط Google، CarInstrumentClusterManager ، توفر CarService مديرًا يقوم بتحديث حالة مجموعة الأدوات من InstrumentClusterRenderingService المقيدة. (في هذه الحالة، يشير المنضم إلى خدمات Android .)

خدمة مجموعة الأدوات

يجب على مصنعي المعدات الأصلية إنشاء حزمة Android (APK) تحتوي على فئة فرعية من خدمة ClusterRenderingService متصلة بالشاشة الثانوية. خدمة ClusterRenderingService متصلة بالشاشة الثانوية. لعينة.

يخدم هذا الفصل غرضين:

  • توفر واجهة Android وجهاز العرض Instrument Cluster (الغرض من هذه الصفحة).
  • يتلقى ويعرض تحديثات حالة التنقل، مثل إرشادات التنقل خطوة بخطوة.

بالنسبة للغرض الأول، يجب أن تقوم تطبيقات OEM لـ InstrumentClusterRendererService بتهيئة شاشة العرض الثانوية المستخدمة لعرض المعلومات على الشاشات في مقصورة السيارة وتوصيل هذه المعلومات إلى CarService عن طريق الاتصال بالطرق InstrumentClusterRendererService.setClusterActivityOptions() و InstrumentClusterRendererService.setClusterActivityState() .

بالنسبة للوظيفة الثانية، يجب أن توفر خدمة مجموعة الأدوات تطبيقًا لخدمة ClusterRenderingService متصلاً بشاشة العرض الثانوية. الواجهة التي تستقبل أحداث تحديث حالة التنقل، والتي يتم ترميزها كنوع eventType وبيانات حدث مشفرة في حزمة.

تسلسل التكامل

يوضح الرسم البياني التالي تنفيذ حالة التنقل التي تعرض التحديثات:

تسلسل التكامل

في هذا الرسم التوضيحي، تشير الألوان إلى ما يلي:

يتبع تدفق معلومات حالة التنقل هذا التسلسل:

  1. يقوم CarService بتهيئة InstrumentClusterRenderingService .
  2. أثناء التهيئة، تقوم InstrumentClusterRenderingService بتحديث CarService بما يلي:
    1. خصائص عرض مجموعة الأدوات، مثل الحدود غير الغامضة (راجع المزيد من التفاصيل حول الحدود غير الغامضة لاحقًا).
    2. خيارات النشاط اللازمة لبدء الأنشطة داخل شاشة عرض مجموعة الأدوات (راجع المزيد من التفاصيل في ActivityOptions .
  3. أحد تطبيقات التنقل (مثل خرائط Google لنظام Android Automotive أو أي تطبيق خرائط يتمتع بالأذونات المطلوبة):
    1. يحصل على CarAppFocusManager باستخدام فئة السيارة من car-lib.
    2. قبل بدء الاتجاهات خطوة بخطوة، يتم استدعاء CarAppFocusManager.requestFocus() لتمرير CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION كمعلمة appType .
  4. يقوم CarAppFocusManager بإرسال هذا الطلب إلى CarService . في حالة الموافقة، تقوم CarService بفحص حزمة تطبيق التنقل وتحديد موقع النشاط المميز بالفئة android.car.cluster.NAVIGATION .
  5. إذا تم العثور عليه، يستخدم تطبيق التنقل ActivityOptions التي تم الإبلاغ عنها بواسطة InstrumentClusterRenderingService لبدء النشاط ويتضمن خصائص عرض مجموعة الآلات كإضافات في الهدف.

دمج واجهة برمجة التطبيقات

يجب أن يكون تنفيذ InstrumentClusterRenderingService :

  • يتم تعيينها كخدمة فردية عن طريق إضافة القيمة التالية إلى AndroidManifest.xml. يعد ذلك ضروريًا لضمان تشغيل نسخة واحدة من خدمة Instrument Cluster، حتى أثناء التهيئة وتبديل المستخدم:
    android:singleUser="true"
  • احتفظ بإذن نظام BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE . وهذا يضمن أن خدمة عرض مجموعة الأدوات المضمنة كجزء من صورة نظام Android فقط هي التي تكون ملزمة بخدمة CarService :
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

تنفيذ InstrumentClusterRenderingService

لبناء الخدمة:

  1. كتابة فئة تمتد من خدمة ClusterRenderingService متصلة بالشاشة الثانوية.
  2. ثم قم بإضافة الإدخال المقابل إلى ملف AndroidManifest.xml الخاص بك. تتحكم هذه الفئة في شاشة عرض مجموعة الأدوات ويمكنها ( اختياريًا ) عرض بيانات Navigation State API.
  3. أثناء onCreate() ، استخدم هذه الخدمة لتهيئة الاتصال مع أجهزة العرض. تشمل الخيارات ما يلي:
    • تحديد الشاشة الثانوية التي سيتم استخدامها لمجموعة العدادات.
    • قم بإنشاء شاشة عرض افتراضية بحيث يقوم تطبيق Instrument Cluster بعرض الصورة المعروضة ونقلها إلى وحدة خارجية (باستخدام تنسيق دفق الفيديو، مثل H.264).
  4. عندما يكون العرض المشار إليه أعلاه جاهزًا، يجب على هذه الخدمة الاتصال بـ InstrumentClusterRenderingService#setClusterActivityLaunchOptions() لتحديد ActivityOptions الدقيقة التي يجب استخدامها لعرض نشاط على مجموعة الأدوات. استخدم هذه المعلمات:
    • فئة. خدمة ClusterRenderingService متصلة بالشاشة الثانوية.
    • ActivityOptions. مثيل ActivityOptions الذي يمكن استخدامه لبدء نشاط في مجموعة الأدوات. على سبيل المثال، من نموذج تطبيق مجموعة الأدوات على AOSP:
      getService().setClusterActivityLaunchOptions(
         CATEGORY_NAVIGATION,
         ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
      
  5. عندما تكون مجموعة الأدوات جاهزة لعرض الأنشطة، يجب أن تقوم هذه الخدمة باستدعاء InstrumentClusterRenderingService#setClusterActivityState() . استخدم هذه المعلمات:
    • يتم توصيل خدمة category ClusterRenderingService بالشاشة الثانوية.
    • يتم توصيل حزمة state التي تم إنشاؤها باستخدام خدمة ClusterRenderingService بالشاشة الثانوية.
    • تأكد من تقديم البيانات التالية:
      • visible يحدد مجموعة الأدوات على أنها مرئية وجاهزة لعرض المحتوى.
      • unobscuredBounds مستطيل يحدد المنطقة الموجودة داخل شاشة عرض مجموعة الأدوات حيث يكون المحتوى آمنًا لعرضه. على سبيل المثال، المناطق التي تغطيها الأقراص وأجهزة القياس.
  6. تجاوز طريقة Service#dump() ومعلومات حالة التقرير المفيدة لتصحيح الأخطاء (راجع dumpsys لمزيد من المعلومات).

نموذج لتنفيذ InstrumentClusterRenderingService

يوضح المثال التالي تنفيذ InstrumentClusterRenderingService ، الذي يقوم بإنشاء VirtualDisplay لتقديم محتوى مجموعة الآلات على شاشة عرض فعلية عن بعد.

وبدلاً من ذلك، يمكن أن يمرر هذا الرمز 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

توفر واجهة برمجة التطبيقات CarAppFocusManager طريقة تسمى getAppTypeOwner() ، والتي تسمح لخدمة المجموعة التي كتبها مصنعو المعدات الأصلية بمعرفة تطبيق التنقل الذي يركز على التنقل في أي وقت محدد. يمكن لمصنعي المعدات الأصلية استخدام طريقة CarAppFocusManager#addFocusListener() الموجودة، ثم استخدام getAppTypeOwner() لمعرفة التطبيق الذي يركز عليه. باستخدام هذه المعلومات، يمكن لمصنعي المعدات الأصلية:

  • قم بتبديل النشاط الموضح في المجموعة إلى نشاط المجموعة الذي يوفره تطبيق التنقل مع التركيز.
  • يمكن اكتشاف ما إذا كان تطبيق التنقل المركّز يحتوي على نشاط جماعي أم لا. إذا لم يكن تطبيق التنقل المركز يحتوي على نشاط مجموعة (أو إذا تم تعطيل هذا النشاط)، فيمكن لمصنعي المعدات الأصلية إرسال هذه الإشارة إلى 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 تطبيقًا نموذجيًا يقوم بتنفيذ واجهة برمجة تطبيقات حالة التنقل.

لتشغيل نموذج التطبيق هذا:

  1. قم بإنشاء Android Auto وتحديثه على HU مدعوم. استخدم بناء Android والتعليمات الوامضة الخاصة بجهازك. للحصول على التعليمات، راجع استخدام اللوحات المرجعية .
  2. قم بتوصيل شاشة ثانوية فعلية بوحدة HU (إذا كانت مدعومة) أو قم بتشغيل وحدة HU الثانوية الافتراضية:
    1. حدد وضع المطور في تطبيق الإعدادات.
    2. انتقل إلى الإعدادات > النظام > خيارات متقدمة > خيارات المطور > محاكاة شاشات العرض الثانوية .
  3. إعادة تشغيل HU. خدمة ClusterRenderingService متصلة بالشاشة الثانوية.
  4. لتشغيل تطبيق KitchenSink:
    1. افتح الدرج.
    2. اذهب الى انست. تَجَمَّع .
    3. انقر فوق بدء البيانات الوصفية .

يطلب KitchenSink التركيز على NAVIGATION، الذي يوجه خدمة DirectRenderingCluster لعرض واجهة مستخدم وهمية على مجموعة الأدوات.