ใช้ Instrument Cluster API (Android API) เพื่อแสดงแอปการนำทาง
ซึ่งรวมถึง Google แผนที่ บนจอแสดงผลรองในรถ เช่น ด้านหลัง
พวงมาลัยบนแผงหน้าปัด หน้านี้จะอธิบายวิธีสร้าง
เพื่อควบคุมจอแสดงผลรองดังกล่าว และเพื่อผสานรวมบริการกับ
CarService
เพื่อให้แอปการนำทางแสดง
ของอินเทอร์เฟซผู้ใช้
คำศัพท์
หน้านี้ใช้คำต่อไปนี้
CarManager
ที่อนุญาตให้แอปภายนอกเปิดกิจกรรมบน
คลัสเตอร์ของเครื่องและรับ Callback เมื่อแผงหน้าปัดพร้อมแสดง
กิจกรรมandroid:singleUser
ที่
ในเวลาใดก็ตาม บริการส่วนใหญ่จะทำงานบนระบบ Androidสิ่งที่ต้องมีก่อน
ก่อนที่จะดำเนินการต่อ โปรดมีองค์ประกอบต่อไปนี้
- สภาพแวดล้อมในการพัฒนาซอฟต์แวร์ Android วิธีตั้งค่า Android ดูสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ ข้อกำหนดของบิลด์
- ดาวน์โหลดซอร์สโค้ด Android ดาวน์โหลดเวอร์ชันล่าสุดของ ซอร์สโค้ด Android จากสาขา Pi-car-release (หรือสูงกว่า) ที่ https://android.googlesource.com
- ระบบเครื่องเสียง (HU) อุปกรณ์ Android ที่วิ่งได้ Android 9 (ขึ้นไป) อุปกรณ์นี้ต้องมีจอแสดงผลเป็นของตัวเองและ การแสดงผลด้วย Android เวอร์ชันใหม่
- คลัสเตอร์เครื่องดนตรีเป็นหนึ่งในรายการต่อไปนี้
- จอแสดงผลสำรองที่จับต้องได้ซึ่งแนบอยู่กับ HU หาก ฮาร์ดแวร์ของอุปกรณ์และเคอร์เนลจะรองรับการจัดการหลายจอแสดงผล
- หน่วยงานอิสระ หน่วยประมวลผลที่เชื่อมต่อกับ HU ผ่านการเชื่อมต่อเครือข่าย รับและแสดงสตรีมวิดีโอได้ บนหน้าจอของตัวเอง
- จอแสดงผลจำลอง ในระหว่างการพัฒนา คุณสามารถใช้
สภาพแวดล้อมจำลองเหล่านี้
- จอแสดงผลรองจำลอง วิธีเปิดใช้การจำลอง จอแสดงผลสำรองสำหรับ AOSP สำหรับ Android ทุกรุ่น ให้ไปที่ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ การตั้งค่าในแอประบบการตั้งค่า จากนั้นเลือกจำลองการตั้งค่ารอง จอแสดงผล การกำหนดค่านี้เทียบเท่ากับการแนบอุปกรณ์แสดงผล ดิสเพลย์นี้ โดยมีข้อจำกัดว่าการแสดงผลนี้จะซ้อนทับบนจอแสดงผลหลัก จอแสดงผล
- แผงหน้าปัดจำลอง โปรแกรมจำลองของ Android มีให้ ด้วย AAOS จะมีตัวเลือกในการแสดงแผงหน้าปัดที่มี ClusterRenderingService
สถาปัตยกรรมการผสานรวม
คอมโพเนนต์การผสานรวม
การผสานรวม Instrument Cluster API ประกอบด้วยองค์ประกอบ 3 อย่างต่อไปนี้
CarService
- แอปการนำทาง
- บริการคลัสเตอร์เครื่องมือ OEM
บริการด้านรถยนต์
CarService
เป็นสื่อกลางระหว่างแอปการนำทางและรถยนต์ โดยตรวจสอบว่ามีเพียง
แอปนำทาง 1 แอปทำงานอยู่ในช่วงเวลาหนึ่งๆ และมีเฉพาะแอปที่มี
สิทธิ์android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL
สามารถส่งข้อมูลได้
รถยนต์
CarService
เปิดเครื่องบริการเฉพาะรถยนต์ทั้งหมดและให้สิทธิ์เข้าถึง
เหล่านี้ผ่านชุดผู้จัดการ หากต้องการโต้ตอบกับบริการ
แอปที่กำลังทำงานในรถสามารถเข้าถึงเครื่องมือจัดการเหล่านี้
สำหรับการใช้แผงหน้าปัด OEM ยานยนต์ต้องสร้างการกำหนดค่าที่กำหนดเอง การใช้งาน InstrumentClusterRendererService และอัปเดต ClusterRenderingService
เมื่อแสดงผลแผงหน้าปัด ในระหว่างขั้นตอนการเปิดเครื่อง
CarService
อ่านคีย์ InstrumentClusterRendererService
ของ
ClusterRenderingService
เพื่อค้นหาการใช้งาน InstrumentClusterService
ใน AOSP รายการนี้
ชี้ไปที่บริการแสดงผลการใช้งานคลัสเตอร์ตัวอย่างของ Navigation State API:
<string name="instrumentClusterRendererService"> android.car.cluster/.ClusterRenderingService </string>
บริการที่อ้างอิงในรายการนี้มีการเริ่มต้นและผูกกับ
CarService
เมื่อแอปนำทาง เช่น Google Maps ให้ขอ
CarInstrumentClusterManager
, CarService
จะระบุผู้จัดการที่
อัปเดตสถานะคลัสเตอร์เครื่องมือจากขอบเขต InstrumentClusterRenderingService
(ในกรณีนี้ bound หมายถึง
แอนดรอยด์
บริการ)
บริการแผงหน้าปัด
OEM ต้องสร้าง Android Package (APK) ที่มีคลาสย่อยของ ClusterRenderingService
ชั้นเรียนนี้มีวัตถุประสงค์ 2 ประการ ได้แก่
- มีอินเทอร์เฟซ Android และอุปกรณ์แสดงผลแผงหน้าปัด (วัตถุประสงค์ของหน้านี้)
- รับและแสดงผลการอัปเดตสถานะการนำทาง เช่น แบบเลี้ยวต่อเลี้ยว คำแนะนำการนำทาง
วัตถุประสงค์ข้อแรกคือการติดตั้งใช้งาน OEM ของ InstrumentClusterRendererService
ต้องเริ่มต้นจอแสดงผลรองที่ใช้แสดงผลข้อมูลบนหน้าจอในห้องโดยสารรถยนต์ และ
สื่อสารข้อมูลนี้กับ CarService
โดยโทรไปที่
InstrumentClusterRendererService.setClusterActivityOptions()
และ
InstrumentClusterRendererService.setClusterActivityState()
เมธอด
สำหรับฟังก์ชันที่ 2 บริการคลัสเตอร์เครื่องดนตรีต้องระบุแอตทริบิวต์
การนำ
ClusterRenderingService
อินเทอร์เฟซที่ได้รับเหตุการณ์การอัปเดตสถานะการนำทาง ซึ่งเข้ารหัสเป็น
eventType
และข้อมูลเหตุการณ์ที่เข้ารหัสในกลุ่ม
ลำดับการผสานรวม
แผนภาพต่อไปนี้แสดงการใช้งานสถานะการนำทาง ที่แสดงผลการอัปเดต:
ในภาพนี้ สีต่างๆ หมายถึงสิ่งต่อไปนี้:
- สีเหลือง
CarService
และCarNavigationStatusManager
ที่ให้บริการโดยแพลตฟอร์ม Android ดูข้อมูลเพิ่มเติมได้ที่ รถยนต์ และ CAR_NAVIGATION_SERVICE - เขียวแกมน้ำเงิน ใช้
InstrumentClusterRendererService
แล้ว โดย OEM - ม่วง แอปการนำทางที่ Google และบุคคลที่สามใช้งาน
- เขียว
CarAppFocusManager
ดูข้อมูลเพิ่มเติมได้ที่ การใช้ CarAppFocusManager API ด้านล่างและ CarAppFocusManager
ขั้นตอนข้อมูลสถานะการนำทางเป็นไปตามลำดับต่อไปนี้
CarService
จะเริ่มต้นInstrumentClusterRenderingService
- ระหว่างการเริ่มต้น ระบบจะอัปเดต
InstrumentClusterRenderingService
CarService
ด้วย:- คุณสมบัติการแสดงผลแผงหน้าปัด เช่น ขอบที่ไม่ชัด (ดูรายละเอียดเพิ่มเติมเกี่ยวกับขอบเขตที่คลุมเครือในภายหลัง)
- ต้องใช้ตัวเลือกกิจกรรมเพื่อเริ่มกิจกรรมภายในจอแสดงผลแผงหน้าปัด ดูข้อมูลเพิ่มเติมได้ที่ ActivityOptions
- แอปนำทาง (เช่น Google Maps สำหรับ Android Automotive หรือแอปแผนที่อื่นๆ
ที่มีสิทธิ์ที่จำเป็น)
- รับ
CarAppFocusManager
โดยใช้คลาส Car จาก Car-lib - ก่อนที่เส้นทางแบบเลี้ยวต่อเลี้ยวจะเริ่มขึ้น โทรไปที่
อีก
CarAppFocusManager.requestFocus()
จึงจะผ่านCarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION
ในฐานะappType
พารามิเตอร์
- รับ
CarAppFocusManager
สื่อสารคำขอนี้กับCarService
หากได้รับอนุญาตCarService
จะตรวจสอบแพ็กเกจแอปการนำทางและค้นหา ทำเครื่องหมายกิจกรรมด้วยหมวดหมู่android.car.cluster.NAVIGATION
แล้ว- หากพบ แอปการนำทางจะใช้
ActivityOptions
ที่รายงานโดยInstrumentClusterRenderingService
เพื่อเริ่มกิจกรรมและรวม คุณสมบัติการแสดงผลแผงหน้าปัดเป็นเครื่องมือเพิ่มเติมในความตั้งใจ
ผสานรวม API
การใช้งาน InstrumentClusterRenderingService
ต้องมีลักษณะดังนี้
- มีการระบุว่าเป็นบริการซิงเกิลตันโดยการเพิ่มค่าต่อไปนี้ลงใน
AndroidManifest.xml ซึ่งเป็นสิ่งจำเป็นเพื่อดูแลให้มีสำเนา
บริการคลัสเตอร์เครื่องมือจะทำงานแม้ในระหว่างการเริ่มต้นและการเปลี่ยนผู้ใช้:
วันที่android:singleUser="true"
- ถือสิทธิ์ระบบ
BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE
ค้างไว้ ช่วงเวลานี้ เพื่อรับประกันว่าเฉพาะบริการแสดงผลคลัสเตอร์ของ Instrument จะเป็นสิ่งหนึ่ง ของอิมเมจระบบ 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.
ClusterRenderingServiceActivityOptions.
อินสแตนซ์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 เพื่อดูว่าแอปการนำทางใดมีการมุ่งเน้นด้านการนำทาง
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(..)
เพื่อเรียกแพ็กเกจ
ชื่อเจ้าของปัจจุบันของประเภทแอปที่กำหนดที่กําลังมุ่งเน้น เมธอดนี้อาจแสดงผล
มีชื่อแพ็กเกจมากกว่า 1 ชื่อ หากเจ้าของปัจจุบันใช้ฟีเจอร์ 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
วิธีเรียกใช้แอปตัวอย่างนี้
- สร้างและแฟลช Android Auto ใน HU ที่รองรับ ใช้เมนู วิธีการสร้าง Android และการแฟลชสำหรับอุปกรณ์ของคุณโดยเฉพาะ โปรดดูวิธีการที่หัวข้อ การใช้กระดานอ้างอิง
- เชื่อมต่อจอแสดงผลรองทางกายภาพกับ HU (หากรองรับ) หรือเปิดอุปกรณ์เสมือน
HU รอง:
- เลือกโหมดนักพัฒนาซอฟต์แวร์ในแอปการตั้งค่า
- ไปที่การตั้งค่า > ระบบ > ขั้นสูง > ตัวเลือกของนักพัฒนาซอฟต์แวร์ > จำลองจอแสดงผลสำรอง
- รีบูต HU
- วิธีการเปิดแอป KitchenSink มีดังนี้
- เปิดลิ้นชัก
- ไปที่ Inst. คลัสเตอร์
- คลิกเริ่มข้อมูลเมตา
KitchenSink ขอโฟกัสการไปยังส่วนต่างๆ ซึ่งจะสั่งให้ DirectRenderingCluster
เพื่อแสดงอินเทอร์เฟซผู้ใช้จำลองบนแผงหน้าปัด