בקטע הזה מוסבר איך אפשר להשתמש ב-Navigation SDK עם ספריית האפליקציות של Android למכוניות כדי להציג את חוויית הניווט של האפליקציה ביחידות מרכזיות בלוח המחוונים. אם המערכת בלוח המחוונים של המשתמש תומכת ב-Android Auto, המשתמשים יכולים להשתמש באפליקציה שלכם ישירות במסך של המכונית על ידי חיבור הטלפון ליחידה. ההנחיות הקוליות מושמעות גם ברמקולים של הרכב.
ספריית האפליקציות של Android למכוניות מאפשרת להפעיל אפליקציות ל-Android ב-Android Auto. היא מספקת קבוצה של תבניות חזותיות שאושרו מבחינת בטיחות הנהג. התבניות האלה מגבילות בכוונה את אמצעי הבקרה בממשק המשתמש של לוח הבקרה, כך שהם לא זהים לאלה של הטלפון, כדי להפחית את הסחת הדעת של הנהג.
כשמפעילים באפליקציה שמבוססת על Navigation SDK את האפשרות לעבוד עם Android Auto, מספקים תצוגה נוספת לחוויית הניווט.
כך אפשר להציג שתי תצוגות של המפה – אחת בטלפון ואחת ביחידת הראש. שני המסכים מקבלים הנחיות מ-Navigator.java
, שהוא סינגלטון.
המערכת בלוח הבקרה מציגה את הרכיבים האינטראקטיביים שאושרו מבחינת בטיחות, כדי שהמשתמש יוכל לנווט בבטחה ליעד שלו בלי הסחות דעת מיותרות. המשתמש יכול גם ליצור אינטראקציה עם פונקציות ספציפיות לאפליקציה, כמו אישור או דחייה של הזמנות, או הצגת מיקום הלקוח במפה. עדכוני סטטוס ההזמנה יכולים להופיע גם ביחידה בלוח הבקרה.
הטלפון המחובר יכול להמשיך להציג את חוויית השימוש הרגילה ב-Navigation SDK או כל תצוגה או תהליך עבודה אחרים באפליקציה. התכונה הזו מאפשרת לכם להמשיך לספק פונקציונליות מותאמת אישית שאולי לא תפעל טוב במסך של הרכב.
הגדרה
החלק הראשון בהגדרת האפליקציה כך שתפעל עם Android Auto כולל הגדרת שירות רכב באמצעות Android Auto, ולאחר מכן הפעלת הספרייה TurnByTurn באפליקציית Navigation SDK.
איך מתחילים להשתמש ב-Android Auto
לפני שמתחילים לעבוד עם התכונות של Navigation SDK שנועדו לעבוד עם Android Auto, צריך להגדיר שירות רכב לאפליקציה כדי ש-Android Auto יוכל לזהות אותה.
פועלים לפי השלבים הבאים, שכולם מופיעים במסמכי התיעוד למפתחים של Android for Cars:
- כדאי להכיר את התכונות הבסיסיות של Android Auto.
- מתקינים את ספריית האפליקציות של Android למכוניות.
- מגדירים את קובץ המניפסט של האפליקציה כך שיכלול את Android Auto.
- מצהירים על רמה מינימלית של אפליקציה לרכב (1) במניפסט.
- יוצרים את
CarAppService
ואת הסשן.
הגדרת Navigation SDK
אחרי שתקימו את שירות האפליקציה לרכב, תוכלו להתחיל לעבוד עם Navigation SDK.
- מגדירים את הפרויקט, אם עדיין לא שילבתם את Navigation SDK באפליקציה.
- מפעילים את הפיד של ההנחיות המפורטות לגבי המסלול באפליקציה.
- אופציונלי. שימוש בסמלים שנוצרו מ-Navigation SDK.
- מציירים את המפה
באמצעות המחלקה
NavigationViewForAuto
ב-Android Auto Surface שסופקה במחלקהScreen
. - מאכלסים את תבנית הניווט של Android Auto בנתונים מספריית ההוראות המפורטות.
עכשיו, אחרי שיש לכם שירות רשום לאספקת מידע על ניווט לאפליקציה, והאפליקציה יכולה להתחבר ל-Android Auto, אתם מוכנים ליצור את שאר רכיבי הניווט שנדרשים כדי שהאפליקציה תפעל בצורה תקינה עם Android Auto:
- ציור של מפת הניווט וממשק המשתמש
- הפעלת אינטראקציה עם המפה
- הצגת הוראות ניווט
- איך מוודאים שסוגי התמרונים נכונים
ציור של ממשק המשתמש של המפה והניווט
הסיווג NavigationViewForAuto
מעבד מפה וממשק משתמש של ניווט במסכי Android Auto. הוא מספק את רוב הפונקציות של NavigationView
בטלפונים, אבל עם אינטראקטיביות מוגבלת. אפשר להשתמש ב-NavigationViewForAuto
כדי לצייר על המשטח שמוצג ב-Android Auto:
private boolean isSurfaceReady(SurfaceContainer surfaceContainer) {
return surfaceContainer.getSurface() != null
&& surfaceContainer.getDpi() != 0
&& surfaceContainer.getHeight() != 0
&& surfaceContainer.getWidth() != 0;
}
@Override
public void onSurfaceAvailable(@NonNull SurfaceContainer surfaceContainer) {
if (!isSurfaceReady(surfaceContainer)) {
return;
}
virtualDisplay =
getCarContext()
.getSystemService(DisplayManager.class)
.createVirtualDisplay(
VIRTUAL_DISPLAY_NAME,
surfaceContainer.getWidth(),
surfaceContainer.getHeight(),
surfaceContainer.getDpi(),
surfaceContainer.getSurface(),
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
presentation = new Presentation(getCarContext(), virtualDisplay.getDisplay());
navigationView = new NavigationViewForAuto(getCarContext());
navigationView.onCreate(null);
navigationView.onStart();
navigationView.onResume();
presentation.setContentView(navigationView);
presentation.show();
navigationView.getMapAsync(googleMap -> this.googleMap = googleMap);
}
@Override
public void onSurfaceDestroyed(@NonNull SurfaceContainer surfaceContainer) {
navigationView.onPause();
navigationView.onStop();
navigationView.onDestroy();
presentation.dismiss();
virtualDisplay.release();
}
הפעלת אינטראקציה עם המפה
כדי לשמור על בטיחות הנהג, Android Auto מגביל את האינטראקציה עם מסך המכשיר לסדרה של שיטות SurfaceCallback. אפשר להשתמש בפונקציות הקריאה החוזרת האלה כדי לתמוך באינטראקציה מוגבלת של הנהג עם המפה במסך בלוח המחוונים. לדוגמה, onClick
ו-onScale
מתאימים למחוות הקשה וצביטה של המשתמש. פונקציות הקריאה החוזרת של האינטראקטיביות צריכות להשתמש ב-map
action
strip באופן הבא:
כדי לקבל קריאות חוזרות (callback) של אינטראקטיביות במפה, האפליקציה צריכה להשתמש בלחצן Action.PAN.
כדי לתמוך בפעולות נוספות של משתמשים, מוסיפים כפתורים לשורת הפעולות במפה.
הפעלת קריאות חוזרות (callback) של משטחים
@NonNull
@Override
public Template onGetTemplate() {
return new NavigationTemplate.Builder()
.setActionStrip(new ActionStrip.Builder().build())
.setMapActionStrip(new ActionStrip.Builder().addAction(Action.PAN).build())
.build();
}
שינוי מרחק התצוגה באמצעות צביטה
@Override
public void onScale(float focusX, float focusY, float scaleFactor) {
CameraUpdate update =
CameraUpdateFactory.zoomBy((scaleFactor - 1),
new Point((int) focusX, (int) focusY));
googleMap.animateCamera(update); // map is set in onSurfaceAvailable.
}
הזזה אופקית
@Override
public void onScroll(float distanceX, float distanceY) {
googleMap.moveCamera(CameraUpdateFactory.scrollBy(distanceX, distanceY));
}
הצגת הוראות ניווט
בקטע הזה מוסבר איך להגדיר צופה לפוסטים של ניווט ולאכלס את ההוראות לניווט בתבנית של כרטיס הפנייה.
תבנית הניווט של Android Auto מספקת כרטיס פנייה שמציג פרטי ניווט שקשורים לנסיעה הנוכחית. הספרייה TurnByTurn ב-Navigation SDK מספקת את מידע הניווט הזה, שהקוד שלכם משתמש בו כדי לאכלס את תבנית הניווט של Android Auto.
הגדרת משקיף
בדוגמה הבאה, SampleApplication היא מחלקה של אפליקציה בהתאמה אישית שמנהלת אובייקט MutableLiveData<NavInfo>
. כשהאובייקט observer מקבל עדכון מהאובייקט navigator, הוא מפרסם את האובייקט NavInfo
הזה ב-NavInfoMutableLiveData
שמתוחזק על ידי המחלקה SampleApplication
.
בדוגמה הבאה נרשם אובייקט כצופה באובייקט הזה בהטמעה שלו ב-Android Auto Screen.
public SampleAndroidAutoNavigationScreen(@NonNull CarContext carContext,
SampleApplication application) {
super(carContext);
getCarContext().getCarService(AppManager.class).setSurfaceCallback(this);
application.getNavInfoMutableLiveData().observe(this, this::processNextStep);
}
איכלוס פרטי ניווט
קטע הקוד הבא מראה איך מאכלסים את התבנית של Android Auto בפרטי הניתוב הנוכחיים, כולל השלבים, המרחקים והסמלים. מידע נוסף על רכיבי התצוגה האלה זמין במאמר איך מאכלסים את פיד התצוגה.
מרחיבים כדי לראות את הקוד לדוגמה.
private RoutingInfo currentRoutingInfo; @NonNull @Override public Template onGetTemplate() { NavigationTemplate.Builder navigationTemplateBuilder = new NavigationTemplate.Builder() .setActionStrip(...) .setMapActionStrip(...) if (currentRoutingInfo != null) { navigationTemplateBuilder.setNavigationInfo(currentRoutingInfo); } return navigationTemplateBuilder.build(); } private void processNextStep(NavInfo navInfo) { if (navInfo == null || navinfo.getCurrentStep() == null) { return; } /** * Converts data received from the Navigation data feed * into Android-Auto compatible data structures. For more information * see the "Ensure correct maneuver types" below. */ Step currentStep = buildStepFromStepInfo(navInfo.getCurrentStep()); Distance distanceToStep = buildDistanceFromMeters(navInfo.getDistanceToCurrentStepMeters()); currentRoutingInfo = new RoutingInfo.Builder().setCurrentStep(currentStep, distanceToStep).build(); // Invalidate the current template which leads to another onGetTemplate call. invalidate(); } private Step buildStepFromStepInfo(StepInfo stepInfo) { IconCompat maneuverIcon = IconCompat.createWithBitmap(stepInfo.getManeuverBitmap()); Maneuver.Builder maneuverBuilder = newManeuver.Builder( ManeuverConverter .getAndroidAutoManeuverType(stepInfo.getManeuver())); CarIcon maneuverCarIcon = new CarIcon.Builder(maneuverIcon).build(); maneuverBuilder.setIcon(maneuverCarIcon); Step.Builder stepBuilder = new Step.Builder() .setRoad(stepInfo.getFullRoadName()) .setCue(stepInfo.getFullInstructionText()) .setManeuver(maneuverBuilder.build()); if (stepInfo.getLanes() != null && stepInfo.getLanesBitmap() != null) { for (Lane lane : buildAndroidAutoLanesFromStep(stepInfo)) { stepBuilder.addLane(lane); } IconCompat lanesIcon = IconCompat.createWithBitmap(stepInfo.getLanesBitmap()); CarIcon lanesImage = new CarIcon.Builder(lanesIcon).build(); stepBuilder.setLanesImage(lanesImage); } return stepBuilder.build(); } /* * Constructs a {@code Distance} object in imperial measurement units. * In a real world scenario, units would be based on locale. */ private Distance buildDistanceFromMeters(int distanceMeters) { // Distance can be negative so set the min distance to 0. int remainingFeet = (int) max(0, distanceMeters * DistanceConstants.FEET_PER_METER); double remainingMiles = ((double) remainingFeet) / DistanceConstants.FEET_PER_MILE; // Only use the tenths place digit if distance is less than 10 miles and show // feet if distance is less than 0.25 miles. if (remainingMiles >= DistanceConstants.MIN_MILES_TO_SHOW_INTEGER) { return Distance.create((int) round(remainingMiles), Distance.UNIT_MILES); } else if (remainingMiles >= 0.25) { return Distance.create((int) remainingMiles, Distance.UNIT_MILES); } else { return Distance.create(remainingFeet, Distance.UNIT_FEET); } }
אימות סוגי התמרונים הנכונים
סוגי התמרונים שמשמשים בספריית המכוניות של Android Auto תואמים אחד לאחד לתמרונים שמופיעים בספריית TurnByTurn. עם זאת, צריך להמיר את התמרונים של Navigation SDK להצהרה תקפה בספריית המכוניות של Android Auto. בטבלה הבאה מוצגת התאמה בין כמה שדות, ואחריה כלי להמרה לדוגמה לנוחיותכם.
הוראות מפורטות בספרייה | Android Auto Maneuver |
---|---|
DEPART |
TYPE_DEPART |
DESTINATION |
TYPE_DESTINATION |
DESTINATION_LEFT |
TYPE_DESTINATION_LEFT |
DESTINATION_RIGHT |
TYPE_DESTINATION_RIGHT |
TURN_U_TURN_CLOCKWISE |
TYPE_U_TURN_RIGHT |
ON_RAMP_LEFT |
TYPE_ON_RAMP_NORMAL_LEFT |
ON_RAMP_RIGHT |
TYPE_ON_RAMP_NORMAL_RIGHT |
ON_RAMP_SLIGHT_LEFT |
TYPE_ON_RAMP_SLIGHT_LEFT |
FORK_RIGHT |
TYPE_FORK_RIGHT |
מרחיבים כדי לראות את הקוד לדוגמה.
import com.google.android.libraries.mapsplatform.turnbyturn.model.Maneuver; import com.google.common.collect.ImmutableMap; import javax.annotation.Nullable; /** Converter that converts between turn-by-turn and Android Auto Maneuvers. */ public final class ManeuverConverter { private ManeuverConverter() {} // Map from turn-by-turn Maneuver to Android Auto Maneuver.Type. private static final ImmutableMap<Integer, Integer> MANEUVER_TO_ANDROID_AUTO_MANEUVER_TYPE = ImmutableMap.<Integer, Integer>builder() .put(Maneuver.DEPART, androidx.car.app.navigation.model.Maneuver.TYPE_DEPART) .put(Maneuver.DESTINATION, androidx.car.app.navigation.model.Maneuver.TYPE_DESTINATION) .put( Maneuver.DESTINATION_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_DESTINATION_LEFT) .put( Maneuver.DESTINATION_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_DESTINATION_RIGHT) .put(Maneuver.STRAIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_STRAIGHT) .put(Maneuver.TURN_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_LEFT) .put( Maneuver.TURN_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_RIGHT) .put(Maneuver.TURN_KEEP_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_KEEP_LEFT) .put(Maneuver.TURN_KEEP_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_KEEP_RIGHT) .put( Maneuver.TURN_SLIGHT_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT) .put( Maneuver.TURN_SLIGHT_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT) .put( Maneuver.TURN_SHARP_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SHARP_LEFT) .put( Maneuver.TURN_SHARP_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_SHARP_RIGHT) .put( Maneuver.TURN_U_TURN_CLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_U_TURN_RIGHT) .put( Maneuver.TURN_U_TURN_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_U_TURN_LEFT) .put( Maneuver.MERGE_UNSPECIFIED, androidx.car.app.navigation.model.Maneuver.TYPE_MERGE_SIDE_UNSPECIFIED) .put(Maneuver.MERGE_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_MERGE_LEFT) .put(Maneuver.MERGE_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_MERGE_RIGHT) .put(Maneuver.FORK_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_FORK_LEFT) .put(Maneuver.FORK_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_FORK_RIGHT) .put( Maneuver.ON_RAMP_UNSPECIFIED, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_NORMAL_RIGHT) .put( Maneuver.ON_RAMP_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_NORMAL_LEFT) .put( Maneuver.ON_RAMP_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_NORMAL_RIGHT) .put( Maneuver.ON_RAMP_KEEP_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_NORMAL_LEFT) .put( Maneuver.ON_RAMP_KEEP_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_NORMAL_RIGHT) .put( Maneuver.ON_RAMP_SLIGHT_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_SLIGHT_LEFT) .put( Maneuver.ON_RAMP_SLIGHT_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_SLIGHT_RIGHT) .put( Maneuver.ON_RAMP_SHARP_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_SHARP_LEFT) .put( Maneuver.ON_RAMP_SHARP_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_SHARP_RIGHT) .put( Maneuver.ON_RAMP_U_TURN_CLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_U_TURN_RIGHT) .put( Maneuver.ON_RAMP_U_TURN_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_ON_RAMP_U_TURN_LEFT) .put( Maneuver.OFF_RAMP_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_OFF_RAMP_NORMAL_LEFT) .put( Maneuver.OFF_RAMP_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_OFF_RAMP_NORMAL_RIGHT) .put( Maneuver.OFF_RAMP_KEEP_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT) .put( Maneuver.OFF_RAMP_KEEP_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT) .put( Maneuver.OFF_RAMP_SLIGHT_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT) .put( Maneuver.OFF_RAMP_SLIGHT_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT) .put( Maneuver.OFF_RAMP_SHARP_LEFT, androidx.car.app.navigation.model.Maneuver.TYPE_OFF_RAMP_NORMAL_LEFT) .put( Maneuver.OFF_RAMP_SHARP_RIGHT, androidx.car.app.navigation.model.Maneuver.TYPE_OFF_RAMP_NORMAL_RIGHT) .put( Maneuver.ROUNDABOUT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW) .put( Maneuver.ROUNDABOUT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW) .put( Maneuver.ROUNDABOUT_STRAIGHT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_CW) .put( Maneuver.ROUNDABOUT_STRAIGHT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_CCW) .put( Maneuver.ROUNDABOUT_LEFT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_LEFT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_RIGHT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_RIGHT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_SLIGHT_LEFT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_SLIGHT_LEFT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_SLIGHT_RIGHT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_SLIGHT_RIGHT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_SHARP_LEFT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_SHARP_LEFT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_SHARP_RIGHT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_SHARP_RIGHT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_U_TURN_CLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_U_TURN_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver .TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE) .put( Maneuver.ROUNDABOUT_EXIT_CLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_EXIT_CW) .put( Maneuver.ROUNDABOUT_EXIT_COUNTERCLOCKWISE, androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_EXIT_CCW) .put(Maneuver.FERRY_BOAT, androidx.car.app.navigation.model.Maneuver.TYPE_FERRY_BOAT) .put(Maneuver.FERRY_TRAIN, androidx.car.app.navigation.model.Maneuver.TYPE_FERRY_TRAIN) .put(Maneuver.NAME_CHANGE, androidx.car.app.navigation.model.Maneuver.TYPE_NAME_CHANGE) .buildOrThrow(); /** Represents the roundabout turn angle for a slight turn in either right or left directions. */ private static final int ROUNDABOUT_ANGLE_SLIGHT = 10; /** Represents the roundabout turn angle for a normal turn in either right or left directions. */ private static final int ROUNDABOUT_ANGLE_NORMAL = 45; /** Represents the roundabout turn angle for a sharp turn in either right or left directions. */ private static final int ROUNDABOUT_ANGLE_SHARP = 135; /** Represents the roundabout turn angle for a u-turn in either right or left directions. */ private static final int ROUNDABOUT_ANGLE_U_TURN = 180; /** * Returns the corresponding {@link androidx.car.app.navigation.model.Maneuver.Type} for the given * direction {@link Maneuver} * * @throws {@link IllegalArgumentException} if the given maneuver does not have a corresponding * Android Auto Maneuver type. */ public static int getAndroidAutoManeuverType(@Maneuver int maneuver) { if (MANEUVER_TO_ANDROID_AUTO_MANEUVER_TYPE.containsKey(maneuver)) { return MANEUVER_TO_ANDROID_AUTO_MANEUVER_TYPE.get(maneuver); } throw new IllegalArgumentException( String.format( "Given turn-by-turn Maneuver %d cannot be converted to an Android Auto equivalent.", maneuver)); } /** * Returns the corresponding Android Auto roundabout angle for the given turn {@link Maneuver}. * Returns {@code null} if given maneuver does not involve a roundabout with a turn. */ @Nullable public static Integer getAndroidAutoRoundaboutAngle(@Maneuver int maneuver) { if (maneuver == Maneuver.ROUNDABOUT_LEFT_CLOCKWISE || maneuver == Maneuver.ROUNDABOUT_RIGHT_CLOCKWISE || maneuver == Maneuver.ROUNDABOUT_LEFT_COUNTERCLOCKWISE || maneuver == Maneuver.ROUNDABOUT_RIGHT_COUNTERCLOCKWISE) { return ROUNDABOUT_ANGLE_NORMAL; } if (maneuver == Maneuver.ROUNDABOUT_SHARP_LEFT_CLOCKWISE || maneuver == Maneuver.ROUNDABOUT_SHARP_RIGHT_CLOCKWISE || maneuver == Maneuver.ROUNDABOUT_SHARP_LEFT_COUNTERCLOCKWISE || maneuver == Maneuver.ROUNDABOUT_SHARP_RIGHT_COUNTERCLOCKWISE) { return ROUNDABOUT_ANGLE_SHARP; } if (maneuver == Maneuver.ROUNDABOUT_SLIGHT_LEFT_CLOCKWISE || maneuver == Maneuver.ROUNDABOUT_SLIGHT_RIGHT_CLOCKWISE || maneuver == Maneuver.ROUNDABOUT_SLIGHT_LEFT_COUNTERCLOCKWISE || maneuver == Maneuver.ROUNDABOUT_SLIGHT_RIGHT_COUNTERCLOCKWISE) { return ROUNDABOUT_ANGLE_SLIGHT; } if (maneuver == Maneuver.ROUNDABOUT_U_TURN_CLOCKWISE || maneuver == Maneuver.ROUNDABOUT_U_TURN_COUNTERCLOCKWISE) { return ROUNDABOUT_ANGLE_U_TURN; } return null; } }
מסמכים קשורים
- הפעלת פיד של הנחיות מפורטות: קודם צריך לשלב את הפונקציונליות של הנחיות מפורטות כדי שהאפליקציה תוכל לפעול עם Android Auto.
- אכלוס התצוגה של הפיד: גישה לשדות נתונים למידע על ההנחיות ושימוש בסמלים.