หัวข้อนี้จะอธิบายวิธีใช้ SDK การนำทางที่มีไลบรารีแอป Android สำหรับรถยนต์เพื่อ แสดงประสบการณ์การนำทางของแอปในแดชบอร์ดส่วนหัว หน่วย หากมี ระบบแดชบอร์ดของผู้ใช้รองรับ Android Auto และผู้ใช้สามารถใช้แอปของคุณได้โดยตรง บนจอแสดงผลของรถยนต์ด้วยการเชื่อมต่อโทรศัพท์กับอุปกรณ์ การนำทางด้วยเสียง จะทำงานในลำโพงรถยนต์ด้วย
แอป Android for Cars คลัง ช่วยให้แอปพลิเคชัน Android สามารถทำงานบน Android Auto ด้วยชุดภาพประกอบ เทมเพลตที่ได้รับอนุมัติเพื่อความปลอดภัยของผู้ขับขี่ เทมเพลตเหล่านี้มีจุดประสงค์เพื่อจำกัด การควบคุม UI ในแดชบอร์ดจากในโทรศัพท์เพื่อลดผู้ขับขี่ การเสียสมาธิ
เมื่อคุณทำให้แอปที่ขับเคลื่อนโดย Navigation SDK ทำงานได้
เมื่อใช้ Android Auto คุณจะนำเสนอมุมมองเพิ่มเติมสำหรับประสบการณ์การนำทาง
เพื่อให้สามารถแสดงมุมมองแผนที่ 2 แบบ โดยมุมมองหนึ่งสำหรับโทรศัพท์และอีกมุมมองสำหรับเครื่องเสียง ทั้ง 2 อย่าง
จอแสดงผลจะได้รับคำแนะนำจาก Navigator.java
ซึ่งก็คือรายการเดียว
ระบบในแดชบอร์ดจะแสดงความปลอดภัยแบบอินเทอร์แอกทีฟที่ได้รับอนุมัติ องค์ประกอบ เพื่อให้ผู้ใช้สามารถไปยังปลายทางของตนได้อย่างปลอดภัย โดยไม่เสียสมาธิจนเกินควร และผู้ใช้ยังสามารถโต้ตอบกับ ฟังก์ชันการทำงานเฉพาะแอป เช่น การยอมรับหรือปฏิเสธคำสั่งซื้อ หรือ การดูตำแหน่งของลูกค้าบนแผนที่ การอัปเดตสถานะคำสั่งซื้อยังสามารถ ปรากฏในหน่วยในหน้าแดชบอร์ด
โทรศัพท์ที่แนบสามารถแสดง ประสบการณ์การใช้งาน SDK การนำทาง หรือมุมมองอื่นๆ หรือ เวิร์กโฟลว์ในแอปพลิเคชันของคุณได้ ซึ่งช่วยให้คุณสามารถระบุ ฟังก์ชันที่อาจทํางานได้ไม่ดีบนหน้าจอรถ
ตั้งค่า
ส่วนแรกของการทำให้แอปทำงานด้วย Android Auto เกี่ยวข้องกับการตั้งค่า บริการรถยนต์ด้วย Android Auto แล้วเปิดใช้ไลบรารี TurnByTurn ในแอป Navigation SDK ของคุณ
เริ่มด้วย Android Auto
ก่อนที่คุณจะเริ่มต้นใช้งาน Navigation SDK ที่ออกแบบมาเพื่อทำงานกับ Android Auto คุณต้องตั้งค่าบริการรถยนต์สำหรับ เพื่อให้ Android Auto ค้นพบแอปของคุณได้
โปรดทำตามขั้นตอนเหล่านี้ ซึ่งคุณสามารถดูได้ใน Android สำหรับ นักพัฒนารถยนต์ เอกสารประกอบ:
- ทำความคุ้นเคย ได้ด้วยฟีเจอร์พื้นฐานของ Android Auto
- ติดตั้ง Android for Cars App Library
- กำหนดค่า ไฟล์ Manifest ของแอปเพื่อรวม Android Auto
- ประกาศ ระดับแอปสำหรับรถยนต์ขั้นต่ำอยู่ที่ 1 ในไฟล์ Manifest
- สร้าง
CarAppService
และเซสชันของคุณ
ตั้งค่า Navigation SDK
เมื่อสร้างบริการแอปสำหรับรถยนต์แล้ว คุณก็พร้อมที่จะใช้งาน SDK การนำทาง
- ตั้งค่า ของโปรเจ็กต์ หาก คุณยังไม่ได้ผสานรวม Navigation SDK ในแอปของคุณ
- เปิดใช้คำแนะนำ TurnbyTurn สำหรับแอปของคุณ
- ไม่บังคับ ใช้ไอคอนที่ระบบสร้างขึ้น จาก Navigation SDK
- วาด
แผนที่
ใช้คลาส
NavigationViewForAuto
ใน Android Auto Surface ที่ให้บริการ ในชั้นเรียนScreen
- ป้อนข้อมูลเทมเพลตการนำทางของ Android Auto โดยใช้ข้อมูลจากไลบรารี TurnbyTurn
ตอนนี้คุณใช้บริการที่ลงทะเบียนแล้วสำหรับการให้ข้อมูลการนำทางแก่ แอปของคุณสามารถเชื่อมต่อกับ Android Auto ได้ คุณก็พร้อมที่จะสร้าง องค์ประกอบการนำทางที่เหลือเพื่อให้แอปทำงานได้อย่างถูกต้อง Android Auto
- วาด UI แผนที่และการนำทาง
- เปิดใช้การโต้ตอบกับแผนที่
- แสดงเส้นทางในการนำทาง
- ตรวจสอบประเภทการจัดวางที่ถูกต้อง
วาด UI แผนที่และการนำทาง
คลาส NavigationViewForAuto
แสดง UI แผนที่และการนำทางใน Android
หน้าจออัตโนมัติ ซึ่งมีฟังก์ชันการทำงานส่วนใหญ่เหมือนกับ 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
ใช้ Callback เหล่านี้เพื่อรองรับการโต้ตอบของคนขับกับแผนที่แบบจำกัด
บนหน้าจอ In-dash เช่น onClick
และ onScale
จะสอดคล้องกับการแตะ
และบีบนิ้วจากผู้ใช้ การเรียกกลับของการโต้ตอบต้องใช้แผนที่
การกระทำ
แถบ
ดังนี้
หากต้องการรับ Callback ของการโต้ตอบแผนที่ แอปของคุณต้องใช้ Action.PAN
หากต้องการรองรับการดำเนินการเพิ่มเติมของผู้ใช้ ให้เพิ่มปุ่มในแถบการทำงานบนแผนที่
เปิดใช้ Surface 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>
ไว้ เมื่อผู้สังเกตการณ์ได้รับ
อัปเดตจากออบเจ็กต์ตัวนำทาง โดยจะโพสต์ออบเจ็กต์ NavInfo
นี้ไปที่
NavInfoMutableLiveData
ดูแลรักษาโดยคลาส SampleApplication
ตัวอย่างต่อไปนี้ลงทะเบียนผู้สังเกตการณ์สำหรับออบเจ็กต์นี้ใน การนำ Android Auto มาใช้ หน้าจอ
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 |
---|---|
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 ได้
- ป้อนข้อมูลฟีด display: การเข้าถึง ช่องข้อมูลสำหรับคำแนะนำและใช้ไอคอน