אשכול מכשירים

השתמש ב-API של Cluster Instrument (API של אנדרואיד) כדי להציג אפליקציות ניווט, כולל מפות Google, בתצוגה משנית במכונית, כגון מאחורי גלגל ההגה בלוח המחוונים. דף זה מתאר כיצד ליצור שירות כדי לשלוט באותה תצוגה משנית ולאחר מכן לשלב את השירות עם CarService כך שאפליקציות ניווט יוכלו להציג ממשק משתמש.

טרמינולוגיה

המונחים הבאים משמשים בדף זה:

טווח תיאור
CarInstrumentClusterManager CarManager המאפשר לאפליקציות חיצוניות להפעיל פעילות באשכול המכשיר ולקבל התקשרות חוזרת כאשר אשכול המכשירים מוכן להצגת פעילויות.
CarManager כיתה בסיס של כל המנהלים המשמשים אפליקציות חיצוניות לאינטראקציה עם שירותים ספציפיים לרכב המיושמים על ידי CarService .
CarService שירות פלטפורמת אנדרואיד המספק תקשורת בין אפליקציות חיצוניות (כולל מפות גוגל) ותכונות ספציפיות לרכב, כגון גישה לאשכול מכשירים.
יַעַד היעד הסופי אליו ינווט הרכב.
זמן הגעה זמן הגעה משוער ליעד.
יחידת ראש (HU) יחידת חישוב ראשונית משובצת במכונית. ה-HU מריץ את כל קוד האנדרואיד ומחובר לתצוגה המרכזית במכונית.
אשכול מכשירים תצוגה משנית הממוקמת מאחורי גלגל ההגה ובין מכשירי המכונית. זו יכולה להיות יחידת חישוב עצמאית המחוברת ל-HU דרך הרשת הפנימית של המכונית (CAN bus) או צג משני המחובר ל-HU.
InstrumentClusterRenderingService מחלקת בסיס לשירות המשמש להתממשק עם תצוגת אשכול המכשירים. יצרני OEM חייבים לספק הרחבה של מחלקה זו המקיימת אינטראקציה עם החומרה הספציפית ל-OEM.
אפליקציית KitchenSink אפליקציית בדיקה כלולה ב-Android Automotive.
מַסלוּל נתיב ספציפי שלאורכו מנווט רכב כדי להגיע ליעד.
שירות סינגלטון שירות אנדרואיד עם התכונה android:singleUser . בכל זמן נתון, לכל היותר מופע אחד של השירות פועל על מערכת אנדרואיד.

דרישות מוקדמות

כדי לפתח את האינטגרציה, הקפידו על האלמנטים הבאים:

  • סביבת פיתוח אנדרואיד. כדי להגדיר את סביבת הפיתוח של Android, ראה דרישות בנייה .
  • הורד את קוד המקור של אנדרואיד. קבל את הגרסה העדכנית ביותר של קוד המקור של אנדרואיד מסניף pi-car-release (או מאוחר יותר) בכתובת https://android.googlesource.com .
  • יחידה ראשית (HU). מכשיר אנדרואיד המסוגל להריץ אנדרואיד 9 (או מאוחר יותר). מכשיר זה חייב להיות בעל תצוגה משלו ולהיות מסוגל להבהב את התצוגה עם גרסאות חדשות של אנדרואיד.
  • אשכול מכשירים הוא אחד מהבאים:
    • תצוגה משנית פיזית מחוברת ל-HU. אם חומרת המכשיר והקרנל תומכים בניהול של מספר תצוגות.
    • יחידה עצמאית. כל יחידה חישובית המחוברת ל-HU באמצעות חיבור רשת, המסוגלת לקלוט ולהציג זרם וידאו על הצג שלה.
    • תצוגה מדומה. במהלך הפיתוח, אתה יכול להשתמש באחת מהסביבות המדמות הבאות:
      • תצוגות משניות מדומה. כדי לאפשר תצוגה משנית מדומה בכל הפצת אנדרואיד של AOSP, עבור אל הגדרות אפשרויות המפתח באפליקציית מערכת ההגדרות ולאחר מכן בחר סימולציה של תצוגות משניות. תצורה זו מקבילה לחיבור צג משני פיזי, עם המגבלה שתצוגה זו מונחת על הצג הראשי.
      • אשכול מכשירים מדומה. אמולטור אנדרואיד הכלול ב-Android Automotive מספק אפשרות להציג אשכול מכשירים עם אמולטור אנדרואיד _qemu-pipes . השתמש ביישום אשכול המכשירים הייחוס DirectRenderingCluster כדי להתחבר לתצוגה החיצונית המדומה הזו.

ארכיטקטורת אינטגרציה

רכיבי אינטגרציה

כל שילוב של ה-API של אשכול מכשירים מורכב משלושת הרכיבים הבאים:

  • CarService
  • אפליקציות ניווט
  • שירות אשכול מכשירים OEM

רכיבי אינטגרציה

שירות מכוניות

CarService מתווך בין אפליקציות ניווט לרכב, ומבטיח שרק אפליקציית ניווט אחת פעילה בכל זמן נתון ורק אפליקציות עם הרשאת android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL יכולות לשלוח נתונים לרכב.

CarService את כל השירותים הספציפיים לרכב ומספקת גישה לשירותים אלה באמצעות סדרה של מנהלים. כדי ליצור אינטראקציה עם השירותים, אפליקציות הפועלות במכונית יכולות לגשת למנהלים אלה.

לצורך הטמעת אשכול מכשירים, יצרני ציוד מקורי לרכב חייבים ליצור יישום מותאם אישית של InstrumentClusterRendererService ולעדכן את קובץ config.xml כדי להצביע על ההטמעה המותאמת אישית.

בעת רינדור של Instrument Cluster, במהלך תהליך האתחול, CarService קורא את מפתח InstrumentClusterRendererService של ה- config.xml כדי לאתר מימוש של InstrumentClusterService . ב-AOSP, ערך זה מצביע על שירות העיבוד של יישום אשכולות לדוגמה של Navigation State API:

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

השירות הנזכר בערך זה מאותחל ומחויב ל- CarService . כאשר אפליקציות ניווט, כמו מפות Google, מבקשות CarInstrumentClusterManager , CarService מספקת מנהל שמעדכן את מצב Cluster Instrument מ- InstrumentClusterRenderingService המחובר. (במקרה זה, מחויב מתייחס לשירותי אנדרואיד .)

שירות אשכול מכשירים

יצרני OEM חייבים ליצור חבילת Android (APK) המכילה תת-סיווג של InstrumentClusterRendererService . ראה ClusterRenderingService לדוגמא.

שיעור זה משרת שתי מטרות:

  • מספק ממשק אנדרואיד ומכשיר העיבוד של אשכול מכשירים (מטרת דף זה).
  • מקבל ומציג עדכוני מצב ניווט, כגון הנחיית ניווט מפורטת.

למטרה הראשונה, יישומי OEM של InstrumentClusterRendererService חייבות לאתחל את התצוגה המשנית המשמשת להצגת מידע על מסכים בתא המכונית ולהעביר מידע זה ל- CarService על ידי קריאה לשיטות InstrumentClusterRendererService.setClusterActivityOptions() ו- InstrumentClusterRendererService.setClusterActivityState() .

עבור הפונקציה השנייה, שירות Cluster Instrument חייב לספק יישום של ממשק NavigationRenderer המקבל אירועים של עדכון מצב ניווט, המקודדים כ- eventType ונתוני אירוע המקודדים בחבילה.

רצף אינטגרציה

התרשים הבא ממחיש את היישום של מצב ניווט שמציג עדכונים:

רצף אינטגרציה

באיור זה, צבעים מציינים את הדברים הבאים:

  • צהוב. CarService ו- CarNavigationStatusManager מסופקים על ידי פלטפורמת אנדרואיד.
  • טורקיז. InstrumentClusterRendererService מיושם על ידי ה-OEM.
  • סָגוֹל. אפליקציית הניווט המיושמת על ידי גוגל ומפתחי צד שלישי.
  • ירוק. CarAppFocusManager .

זרימת המידע על מצב הניווט עוקבת אחר הרצף הזה:

  1. CarService מאתחל את InstrumentClusterRenderingService .
  2. במהלך האתחול, InstrumentClusterRenderingService מעדכן את CarService ב:
    1. מאפייני תצוגה של אשכול מכשירים, כגון גבולות לא ברורים (ראה פרטים נוספים על גבולות לא ברורים מאוחר יותר).
    2. אפשרויות הפעילות הדרושות להפעלת פעילויות בתוך תצוגת אשכול המכשירים (ראה פרטים נוספים ב- ActivityOptions .
  3. אפליקציית ניווט (כגון מפות Google עבור 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 כדי להפעיל את הפעילות וכוללת את מאפייני התצוגה של אשכול מכשירים כתוספות בכוונה.

שילוב ה-API

הטמעת InstrumentClusterRenderingService חייבת:

  • הגדר כשירות יחיד על ידי הוספת הערך הבא ל-AndroidManifest.xml. זה הכרחי כדי להבטיח שעתק יחיד של שירות אשכול המכשירים יפעל, אפילו במהלך אתחול ומעבר משתמש:
    android:singleUser="true"
  • החזק את הרשאת המערכת BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE . זה מבטיח שרק שירות העיבוד של אשכול המכשירים הכלול כחלק מתמונת מערכת אנדרואיד יהיה תמיד כבול על ידי CarService :
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

הטמעת InstrumentClusterRenderingService

כדי לבנות את השירות:

  1. כתוב מחלקה המשתרעת מ- InstrumentClusterRenderingService ולאחר מכן הוסף ערך מתאים לקובץ AndroidManifest.xml שלך. מחלקה זו שולטת בתצוגת אשכול המכשירים ויכולה ( אופציונלית ) להציג נתוני Navigation State API.
  2. במהלך onCreate() , השתמש בשירות זה כדי לאתחל את התקשורת עם חומרת העיבוד. האפשרויות כוללות:
    • קבע את התצוגה המשנית שתשמש עבור אשכול המכשירים.
    • צור תצוגה וירטואלית כך שאפליקציית אשכול הכלים תעבד ותשדר את התמונה המעובדת ליחידה חיצונית (באמצעות פורמט הזרמת וידאו, כגון H.264).
  3. כאשר התצוגה המצוינת למעלה מוכנה, שירות זה חייב לקרוא InstrumentClusterRenderingService#setClusterActivityLaunchOptions() כדי להגדיר את ה- ActivityOptions המדויק שיש להשתמש בהם כדי להציג פעילות באשכול הכלים. השתמש בפרמטרים הבאים:
    • קטגוריה. CarInstrumentClusterManager#CATEGORY_NAVIGATION
    • ActivityOptions. מופע ActivityOptions שניתן להשתמש בו כדי להפעיל פעילות באשכול המכשירים. לדוגמה, מתוך היישום לדוגמה Instrument Cluster ב-AOSP:
      getService().setClusterActivityLaunchOptions(
         CATEGORY_NAVIGATION,
         ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
      
  4. כאשר Cluster Instrument מוכן להצגת פעילויות, שירות זה חייב להפעיל את InstrumentClusterRenderingService#setClusterActivityState() . השתמש בפרמטרים הבאים:
    • category CarInstrumentClusterManager#CATEGORY_NAVIGATION
    • חבילת state שנוצר עם ClusterActivityState . הקפד לספק את הנתונים הבאים:
      • visible מציין את אשכול המכשירים כגלוי ומוכן להצגת תוכן.
      • unobscuredBounds מלבן המגדיר את האזור בתוך תצוגת אשכול המכשירים שבו בטוח להציג תוכן. לדוגמה, אזורים המכוסים על ידי חוגים ומדדים.
  5. עוקף את שיטת Service#dump() ודווח על מידע סטטוס שימושי לניפוי באגים (ראה dumpsys למידע נוסף).

יישום InstrumentClusterRenderingService לדוגמה

הדוגמה הבאה מתארת ​​יישום InstrumentClusterRenderingService , שיוצר תצוגה VirtualDisplay להצגת תוכן אשכול הכלים על צג פיזי מרוחק.

לחלופין, קוד זה יכול להעביר את 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 that will 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 מספק שיטה בשם 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 application 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 של Navigation State.

כדי להפעיל יישום לדוגמה זה:

  1. בנה והבזק את Android Auto ב-HU נתמך. השתמש במבנה האנדרואיד ובהוראות המהבהבות הספציפיות למכשיר שלך. להנחיות, ראה שימוש בלוחות עזר .
  2. חבר צג משני פיזי ל-HU (אם נתמך) או הפעל את ה-HU המשני הווירטואלי:
    1. בחר מצב מפתח באפליקציית ההגדרות.
    2. עבור אל הגדרות > מערכת > מתקדם > אפשרויות מפתחים > הדמיית תצוגות משניות .
  3. הפעל מחדש את ה-HU. שירות ClusterRenderingService מחובר לתצוגה המשנית.
  4. כדי להפעיל את אפליקציית KitchenSink:
    1. פתח את המגירה.
    2. עבור אל Inst. אשכול .
    3. לחץ על התחל METADATA .

KitchenSink מבקש ממוקד NAVIGATION, אשר מורה לשירות DirectRenderingCluster להציג ממשק משתמש מדומה באשכול הכלים.