השתמשו ב-Instrument Cluster API (API ל-Android) כדי להציג אפליקציות ניווט.
כולל מפות Google, במסך משני ברכב, למשל מאחורי
את ההגה על לוח המכשירים. בדף הזה נסביר איך ליצור
שירות כדי לשלוט בתצוגה המשנית ולשלב את השירות עם
CarService
כדי שאפליקציות ניווט יוכלו להציג
ממשק משתמש גרפי.
טרמינולוגיה
המונחים הבאים מופיעים בדף הזה.
CarManager
שמאפשר לאפליקציות חיצוניות להפעיל פעילות ב-
אשכול הכלים ולקבל קריאות חוזרות (callback) כשאשכול הכלים מוכן להצגה
פעילויות.android:singleUser
. בשעה
בכל זמן נתון, מופע אחד לפחות של השירות פועל במערכת Android.דרישות מוקדמות
לפני שממשיכים, חשוב לוודא שהתנאים הבאים מתקיימים:
- סביבת הפיתוח של Android. כדי להגדיר את Android בסביבת הפיתוח, דרישות Build.
- מורידים את קוד המקור של Android. כדאי להוריד את הגרסה האחרונה של את קוד המקור של Android מסניף pi-car-אוטומטית (ואילך) https://android.googlesource.com.
- יחידה ראשית (HU). מכשיר Android שיכול לפעול Android 9 (ואילך). למכשיר הזה צריכה להיות מסך משלו והוא יכול: את המסך החכם עם גרסאות build חדשות של Android.
- אשכול כלים הוא אחד מהבאים:
- מסך משני פיזי שמחובר ל-HU. אם החומרה והליבה של המכשיר תומכות בניהול מסכים מרובים.
- יחידה עצמאית. כל יחידה חישובית שמחוברת HU באמצעות חיבור לרשת, המסוגל לקבל ולהציג וידאו בסטרימינג בתצוגה נפרדת.
- תצוגה שעברה אמולציה. במהלך הפיתוח, אפשר להשתמש באחד
האמולציה של הסביבות הבאות:
- הדמיה של מסכים משניים. כדי להפעיל סימולציה במסך משני בכל הפצת AOSP ל-Android, עוברים אל אפשרויות למפתחים ההגדרות באפליקציית המערכת הגדרות ולאחר מכן בוחרים Simulate משני מציג את התצורה הזו מקבילה לחיבור פיזי משני להצגת מודעות, עם המגבלה שלפיה תצוגה זו מופיעה מעל מסך.
- אשכול כלים אמולציה. האמולטור Android כלול עם AAOS אפשר להציג אשכול כלים עם ClusterRenderingService.
ארכיטקטורת שילוב
רכיבי שילוב
כל שילוב של Instrument Cluster API מורכב משלושת הרכיבים הבאים:
CarService
- אפליקציות ניווט
- שירות אשכול מכשירים של OEM (יצרן ציוד מקורי)
CarService
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
.
(במקרה הזה, המילה bound מתייחסת
Android
שירותים.)
שירות אשכול כלים
יצרני ציוד מקורי חייבים ליצור חבילת Android (APK) שמכילה תת-מחלקה של ClusterRenderingService.
לכיתה הזו יש שתי מטרות:
- מספקת ממשק Android ומכשיר הרינדור של אשכול הכלים (מטרת הדף הזה).
- המערכת מקבלת ומעבדת עדכונים על מצב הניווט, כמו מסלול מפורט הנחיות ניווט.
למטרה הראשונה, הטמעות של ה-OEM (יצרן הציוד המקורי) של InstrumentClusterRendererService
חייב לאתחל את המסך המשני שמשמש לעיבוד מידע על המסכים בתא הנהג ברכב
להעביר את המידע הזה אל CarService
באמצעות פנייה אל
InstrumentClusterRendererService.setClusterActivityOptions()
והקבוצה
InstrumentClusterRendererService.setClusterActivityState()
methods.
עבור הפונקציה השנייה, שירות אשכול הכלים חייב לספק
יישום של
ClusterRenderingService
בממשק שמקבל אירועים לעדכון סטטוס הניווט, שמקודדים
eventType
ונתוני אירועים מקודדים בחבילה.
רצף אינטגרציה
התרשים הבא ממחיש את ההטמעה של מצב ניווט לעיבוד עדכונים:
באיור הזה, הצבעים מציינים את הדברים הבאים:
- צהוב.
CarService
ו-CarNavigationStatusManager
שסופקו על ידי פלטפורמת Android. מידע נוסף זמין במאמר הבא: רכב וגם Car_NAVIGATION_SERVICE. - ציאן. בוצעה הטמעה של
InstrumentClusterRendererService
על ידי ה-OEM. - סגול. אפליקציית הניווט שהוטמעה על ידי Google וצד שלישי למפתחים.
- ירוק.
CarAppFocusManager
. מידע נוסף זמין במאמר הבא: באמצעות CarAppFocusManager API מתחת ל- CarAppFocusManager.
זרימת המידע על מצב הניווט מתבצעת לפי הרצף הבא:
CarService
מאתחל אתInstrumentClusterRenderingService
.- במהלך האתחול,
InstrumentClusterRenderingService
מתעדכןCarService
עם:- מאפייני התצוגה של אשכול הכלים, כמו גבולות לא מעורפלים (בהמשך יש פרטים נוספים על גבולות לא חסומים).
- אפשרויות הפעילות הנדרשות להפעלת פעילויות במסך של אשכול הכלים. מידע נוסף זמין במאמר הבא: ActivityOptions.
- אפליקציית ניווט (כמו מפות Google ל-Android Automotive או אפליקציית מפות כלשהי)
עם ההרשאות הנדרשות):
- מקבל
CarAppFocusManager
באמצעות המחלקה Car-lib. - לפני שמתחילה המסלול המפורט, שיחות אל
CarAppFocusManager.requestFocus()
כדי לעבורCarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION
בתורappType
הפרמטר.
- מקבל
- הבקשה הזו תועבר על ידי
CarAppFocusManager
אלCarService
. אם הבקשה ניתנת,CarService
בודק את החבילה של אפליקציית הניווט ומאתר פעילות סומנה בקטגוריהandroid.car.cluster.NAVIGATION
. - אם האפליקציה תימצא, היא תשתמש ב
ActivityOptions
שמדווחת על ידיInstrumentClusterRenderingService
להפעלת הפעילות, כולל מאפייני התצוגה של אשכול הכלים כתוספות ב-Intent.
משלבים את ה-API
ההטמעה של InstrumentClusterRenderingService
חייבת:
- להיות מוגדר כשירות סינגלטון על ידי הוספת הערך הבא ל-
הקובץ AndroidManifest.xml. דבר זה נדרש כדי להבטיח שעותק יחיד של
שירות אשכול הכלים פועל, גם במהלך האתחול והחלפת המשתמשים:
android:singleUser="true"
- לוחצים לחיצה ארוכה על הרשאת המערכת
BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE
. הזה מבטיח שרק שירות הרינדור של אשכול הכלים כלול כחלק של תמונת המערכת של Android תמיד יהיה מוגבל בCarService
:<uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
הטמעת InstrumentClusterRenderingService
כדי ליצור את השירות:
- כתיבת מחלקה שמתפרסת על
ClusterRenderingService
ולאחר מכן מוסיפים רשומה תואמת לקובץ
AndroidManifest.xml
. הכיתה הזו קובע את התצוגה של אשכול הכלים ויכול (אופציונלי) לעבד את מצב הניווט נתוני API. - במהלך
onCreate()
, אפשר להשתמש בשירות הזה כדי לאתחל את התקשורת עם לחומרת רינדור. האפשרויות כוללות:- קביעת המסך המשני שבו יש להשתמש עבור אשכול הכלים.
- יוצרים תצוגה וירטואלית כדי שאפליקציית אשכול הכלים תעבד ותשדר את תמונה שעברה רינדור ליחידה חיצונית (באמצעות פורמט וידאו בסטרימינג, כמו H.264).
- כשהתצוגה שצוינה למעלה מוכנה, השירות חייב להתקשר
InstrumentClusterRenderingService#setClusterActivityLaunchOptions()
כדי להגדירActivityOptions
בדיוק שצריך להשתמש בו כדי להציג פעילות אשכול כלי נגינה. צריך להשתמש בפרמטרים הבאים:category.
ClusterRenderingService.ActivityOptions.
מופעActivityOptions
שיכול להיות ששימשו להפעלת פעילות באשכול הכלים. לדוגמה, מתוך הטמעת אשכול כלים ב-AOSP:getService().setClusterActivityLaunchOptions( CATEGORY_NAVIGATION, ActivityOptions.makeBasic() .setLaunchDisplayId(displayId));
- כשאשכול הכלים מוכן להצגת פעילויות, שירות זה חייב להפעיל
InstrumentClusterRenderingService#setClusterActivityState()
שימוש באלה :category
ClusterRenderingService.- חבילה אחת (
state
) נוצרה עם ClusterRenderingService. יש לספק את הנתונים הבאים:visible
מציין שאשכול הכלים גלוי ומוכן להציג את התוכן.unobscuredBounds
מלבן שמגדיר את השטח שבתוך תצוגה של אשכול הכלים שבו בטוח להציג תוכן. לדוגמה, אזורים שמכוסים בחוגות ובמדדים.
- שינוי השיטה
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 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) כדי לדעת באיזו אפליקציית ניווט מתמקדים בכל רגע נתון
בזמן האימון. יצרני ציוד מקורי יכולים להשתמש בשיטת 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 מספק אפליקציה לדוגמה שמטמיעה את Navigation State API.
כדי להריץ את האפליקציה לדוגמה:
- גרסת ה-build וה-Flash של Android Auto ב-HU נתמך. משתמשים ב הוראות לפיתוח והבהוב של Android שספציפיות למכשיר שלכם. הוראות מופיעות שימוש בלוחות עזר.
- מחברים מסך פיזי משני ל-HU (אם נתמך) או מפעילים את הווירטואלי
HU משני:
- בוחרים באפשרות מצב פיתוח באפליקציית ההגדרות.
- עוברים אל הגדרות > מערכת > מתקדם > אפשרויות למפתחים > ליצור הדמיה של מסכים משניים.
- הפעלה מחדש של HU
- כדי להפעיל את אפליקציית KitchenSink:
- פותחים את חלונית ההזזה.
- עוברים אל Inst. אשכול.
- לוחצים על הפעלת מטא-נתונים.
היא מבקשת התמקדות ב-NAVIGATION של KitchenSink, לפי הוראה DirectRenderingCluster
שירות להצגת ממשק משתמש מדומה באשכול הכלים.