ใช้ Instrument Cluster API (Android API) เพื่อแสดงแอปการนำทาง รวมถึง Google Maps บนจอแสดงผลรองในรถยนต์ เช่น หลังพวงมาลัยบนแผงหน้าปัด หน้านี้อธิบายวิธีสร้างบริการเพื่อควบคุมจอแสดงผลรองนั้น จากนั้นรวมบริการเข้ากับ
เพื่อให้แอพนำทางสามารถแสดงอินเทอร์เฟซผู้ใช้ได้CarService
คำศัพท์เฉพาะทาง
มีการใช้คำศัพท์ต่อไปนี้ในหน้านี้:
ภาคเรียน | คำอธิบาย |
---|---|
CarInstrumentClusterManager | CarManager ที่ช่วยให้แอพภายนอกสามารถเริ่มกิจกรรมบนแผงหน้าปัดและรับการติดต่อกลับเมื่อแผงหน้าปัดพร้อมที่จะแสดงกิจกรรม |
ผู้จัดการฝ่ายรถยนต์ | คลาสพื้นฐานของผู้จัดการทั้งหมดที่แอปภายนอกใช้เพื่อโต้ตอบกับบริการเฉพาะรถยนต์ที่ดำเนินการโดย CarService |
CarService | บริการแพลตฟอร์ม Android ที่ให้การสื่อสารระหว่างแอปภายนอก (รวมถึง Google Maps) และคุณสมบัติเฉพาะของรถยนต์ เช่น การเข้าถึงแผงหน้าปัด |
ปลายทาง | จุดหมายปลายทางสุดท้ายที่ยานพาหนะจะนำทางไป |
การทางพิเศษแห่งประเทศไทย | เวลาโดยประมาณถึงจุดหมายปลายทาง |
เฮดยูนิต (HU) | หน่วยประมวลผลหลักที่ฝังอยู่ในรถยนต์ HU รันโค้ด Android ทั้งหมดและเชื่อมต่อกับจอแสดงผลส่วนกลางในรถ |
แผงหน้าปัด | จอแสดงผลรองตั้งอยู่ด้านหลังพวงมาลัยและระหว่างแผงหน้าปัดรถยนต์ ซึ่งอาจเป็นหน่วยประมวลผลอิสระที่เชื่อมต่อกับ HU ผ่านเครือข่ายภายในของรถยนต์ (CAN บัส) หรือจอแสดงผลรองที่เชื่อมต่อกับ HU |
InstrumentClusterRenderingService | คลาสพื้นฐานสำหรับบริการที่ใช้เชื่อมต่อกับจอแสดงผลแผงหน้าปัด OEM ต้องจัดเตรียมส่วนขยายของคลาสนี้ที่โต้ตอบกับฮาร์ดแวร์เฉพาะของ OEM |
แอพ KitchenSink | แอปพลิเคชันทดสอบที่มาพร้อมกับ Android Automotive |
เส้นทาง | เส้นทางเฉพาะที่ยานพาหนะนำทางไปถึงจุดหมายปลายทาง |
บริการซิงเกิลตัน | บริการ Android ที่มีแอตทริบิวต์ android:singleUser ในช่วงเวลาใดก็ตาม บริการจะทำงานบนระบบ Android ได้สูงสุด 1 อินสแตนซ์ |
ข้อกำหนดเบื้องต้น
หากต้องการพัฒนาการบูรณาการ ต้องแน่ใจว่ามีองค์ประกอบเหล่านี้:
- สภาพแวดล้อมการพัฒนา Android หากต้องการตั้งค่าสภาพแวดล้อมการพัฒนา Android โปรดดู ข้อกำหนดของ Build
- ดาวน์โหลดซอร์สโค้ด Android รับซอร์สโค้ด Android เวอร์ชันล่าสุดจากสาขา pi-car-release (หรือใหม่กว่า) ได้ที่ https://android.googlesource.com
- หัวหน้าหน่วย (HU) อุปกรณ์ Android ที่สามารถใช้งาน Android 9 (หรือใหม่กว่า) อุปกรณ์นี้ต้องมีจอแสดงผลของตัวเองและสามารถแฟลชจอแสดงผลด้วย Android รุ่นใหม่ได้
- แผงหน้าปัด เป็นหนึ่งในสิ่งต่อไปนี้:
- จอแสดงผลรองทางกายภาพที่ติดอยู่กับ HU หากฮาร์ดแวร์ของอุปกรณ์และเคอร์เนลรองรับการจัดการจอแสดงผลหลายจอ
- หน่วยอิสระ. หน่วยประมวลผลใดๆ ที่เชื่อมต่อกับ HU ผ่านการเชื่อมต่อเครือข่าย ซึ่งสามารถรับและแสดงสตรีมวิดีโอบนจอแสดงผลของตัวเองได้
- การแสดงผลจำลอง ในระหว่างการพัฒนา คุณสามารถใช้หนึ่งในสภาพแวดล้อมจำลองเหล่านี้:
- จอแสดงผลรองจำลอง หากต้องการเปิดใช้งานการแสดงผลรองที่จำลองบนการกระจาย AOSP Android ใดๆ ให้ไปที่การตั้งค่าตัวเลือกนักพัฒนาในแอปพลิเคชันระบบการตั้งค่า จากนั้นเลือกจำลองการแสดงผลรอง การกำหนดค่านี้เทียบเท่ากับการแนบจอแสดงผลรองทางกายภาพ โดยมีข้อจำกัดว่าจอแสดงผลนี้ซ้อนทับบนจอแสดงผลหลัก
- แผงหน้าปัดจำลอง โปรแกรมจำลอง Android ที่มาพร้อมกับ Android Automotive มีตัวเลือกในการแสดงแผงหน้าปัดพร้อมบริการ ClusterRenderingService ที่เชื่อมต่อกับจอแสดงผลรอง โปรแกรมจำลอง _qemu-pipes บริการ ClusterRenderingService เชื่อมต่อกับจอแสดงผลรอง
การใช้งานแผงหน้าปัดอ้างอิงเพื่อเชื่อมต่อกับจอแสดงผลภายนอกที่จำลองนี้
สถาปัตยกรรมบูรณาการ
ส่วนประกอบบูรณาการ
การบูรณาการใดๆ ของ Instrument Cluster API ประกอบด้วยองค์ประกอบสามส่วนต่อไปนี้:
-
CarService
- แอพนำทาง
- บริการคลัสเตอร์เครื่องมือ OEM
คาร์เซอร์วิส
CarService
จะทำหน้าที่เป็นสื่อกลางระหว่างแอพนำทางและรถยนต์ เพื่อให้มั่นใจว่ามีแอพนำทางเพียงแอพเดียวที่ทำงานอยู่ในช่วงเวลาที่กำหนด และเฉพาะแอพที่ได้รับอนุญาต android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL
เท่านั้นที่สามารถส่งข้อมูลไปยังรถได้
CarService
เริ่มต้นบริการเฉพาะรถยนต์ทั้งหมดและให้การเข้าถึงบริการเหล่านี้ผ่านชุดผู้จัดการ หากต้องการโต้ตอบกับบริการต่างๆ แอปพลิเคชันที่ทำงานอยู่ในรถจะสามารถเข้าถึงผู้จัดการเหล่านี้ได้
สำหรับการใช้งานแผงหน้าปัด OEM ในอุตสาหกรรมยานยนต์จะต้องสร้างการใช้งาน InstrumentClusterRendererService แบบกำหนดเอง และอัปเดตบริการ ClusterRenderingService ที่เชื่อมต่อกับจอแสดงผลรอง
เมื่อเรนเดอร์ Instrument Cluster ในระหว่างกระบวนการบู๊ต CarService
จะอ่านคีย์ InstrumentClusterRendererService
ของบริการ ClusterRenderingService ที่เชื่อมต่อกับจอแสดงผลรอง เพื่อค้นหาการนำ InstrumentClusterService
ไปใช้งาน ใน AOSP รายการนี้ชี้ไปที่บริการแสดงผลการใช้งานคลัสเตอร์ตัวอย่าง Navigation State API:
<string name="instrumentClusterRendererService"> android.car.cluster/.ClusterRenderingService </string>
บริการที่อ้างถึงในรายการนี้ได้รับการเตรียมใช้งานและเชื่อมโยงกับ CarService
เมื่อแอปการนำทาง เช่น Google Maps ขอ CarInstrumentClusterManager
CarService
จะจัดเตรียมผู้จัดการที่อัปเดตสถานะ Instrument Cluster จาก InstrumentClusterRenderingService
ที่ผูกไว้ (ในกรณีนี้ bound หมายถึง บริการ Android )
บริการแผงหน้าปัด
OEM ต้องสร้างแพ็คเกจ Android (APK) ที่มีคลาสย่อยของบริการ ClusterRenderingService ที่เชื่อมต่อกับจอแสดงผลรอง บริการ ClusterRenderingService เชื่อมต่อกับจอแสดงผลรอง สำหรับตัวอย่าง
ชั้นเรียนนี้มีจุดประสงค์สองประการ:
- จัดให้มีอินเทอร์เฟซ Android และอุปกรณ์แสดงผลแผงหน้าปัด (วัตถุประสงค์ของหน้านี้)
- รับและแสดงผลการอัปเดตสถานะการนำทาง เช่น คำแนะนำการนำทางแบบเลี้ยวต่อเลี้ยว
สำหรับวัตถุประสงค์แรก การใช้งาน OEM ของ InstrumentClusterRendererService
ต้องเริ่มต้นจอแสดงผลรองที่ใช้เพื่อแสดงข้อมูลบนหน้าจอในห้องโดยสารรถยนต์ และสื่อสารข้อมูลนี้ไปยัง CarService
โดยการเรียกไปยังเมธอด InstrumentClusterRendererService.setClusterActivityOptions()
และ InstrumentClusterRendererService.setClusterActivityState()
สำหรับฟังก์ชันที่สอง บริการ Instrument Cluster จะต้องจัดให้มีการใช้งานบริการ 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
เพื่อเริ่มกิจกรรมและรวมคุณสมบัติการแสดงผล Instrument Cluster เป็นส่วนเสริมใน Intent
บูรณาการ API
การใช้งาน InstrumentClusterRenderingService
จะต้อง:
- กำหนดให้เป็นบริการซิงเกิลตันโดยการเพิ่มค่าต่อไปนี้ใน AndroidManifest.xml นี่เป็นสิ่งจำเป็นเพื่อให้แน่ใจว่าสำเนาเดียวของบริการ Instrument Cluster จะทำงาน แม้ในระหว่างการเริ่มต้นและการสลับผู้ใช้:
android:singleUser="true"
- ระงับสิทธิ์ระบบ
BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE
สิ่งนี้รับประกันได้ว่าเฉพาะบริการการเรนเดอร์ Instrument Cluster ที่รวมเป็นส่วนหนึ่งของอิมเมจระบบ Android เท่านั้นที่ถูกผูกไว้กับCarService
:<uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
การใช้ InstrumentClusterRenderingService
เพื่อสร้างบริการ:
- เขียนคลาสที่ขยายจากบริการ ClusterRenderingService ที่เชื่อมต่อกับจอแสดงผลรอง จากนั้นเพิ่มรายการที่เกี่ยวข้องลงในไฟล์
- ในระหว่าง
onCreate()
ให้ใช้บริการนี้เพื่อเริ่มต้นการสื่อสารกับฮาร์ดแวร์การเรนเดอร์ ตัวเลือกได้แก่:- กำหนดจอแสดงผลรองที่จะใช้สำหรับแผงหน้าปัด
- สร้างการแสดงผลเสมือนเพื่อให้แอพ Instrument Cluster เรนเดอร์และส่งภาพที่เรนเดอร์ไปยังหน่วยภายนอก (โดยใช้รูปแบบการสตรีมวิดีโอ เช่น H.264)
- เมื่อจอแสดงผลที่ระบุข้างต้นพร้อมแล้ว บริการนี้จะต้องเรียก
InstrumentClusterRenderingService#setClusterActivityLaunchOptions()
เพื่อกำหนดActivityOptions
ที่แน่นอนที่ต้องใช้เพื่อแสดงกิจกรรมบน Instrument Cluster ใช้พารามิเตอร์เหล่านี้:- หมวดหมู่. บริการ ClusterRenderingService เชื่อมต่อกับจอแสดงผลรอง
-
ActivityOptions.
อินสแตนซ์ActivityOptions
ที่สามารถใช้เพื่อเรียกใช้กิจกรรมในแผงหน้าปัด ตัวอย่างเช่น จากตัวอย่างการใช้งาน Instrument Cluster บน AOSP:getService().setClusterActivityLaunchOptions( CATEGORY_NAVIGATION, ActivityOptions.makeBasic() .setLaunchDisplayId(displayId));
- เมื่อ Instrument Cluster พร้อมที่จะแสดงกิจกรรม บริการนี้จะต้องเรียกใช้
InstrumentClusterRenderingService#setClusterActivityState()
ใช้พารามิเตอร์เหล่านี้:-
category
บริการ ClusterRenderingService เชื่อมต่อกับจอแสดงผลรอง -
state
Bundle ที่สร้างด้วยบริการ ClusterRenderingService เชื่อมต่อกับจอแสดงผลรอง อย่าลืมให้ข้อมูลต่อไปนี้: -
visible
ระบุแผงหน้าปัดให้มองเห็นได้และพร้อมที่จะแสดงเนื้อหา -
unobscuredBounds
สี่เหลี่ยมผืนผ้าที่กำหนดพื้นที่ภายในจอแสดงผลแผงหน้าปัดซึ่งปลอดภัยในการแสดงเนื้อหา ตัวอย่างเช่น พื้นที่ที่ครอบคลุมโดยหน้าปัดและเกจ
-
- แทนที่เมธอด
Service#dump()
และข้อมูลสถานะรายงานที่เป็นประโยชน์สำหรับการดีบัก (ดูข้อมูลเพิ่มเติมที่ dumpsys )
AndroidManifest.xml
ของคุณ คลาสนี้ควบคุมการแสดงผลแผงหน้าปัดและสามารถ ( เป็นทางเลือก ) แสดงผลข้อมูล API สถานะการนำทางตัวอย่างการใช้งาน InstrumentClusterRenderingService
ตัวอย่างต่อไปนี้สรุปการใช้งาน InstrumentClusterRenderingService
ซึ่งสร้าง VirtualDisplay
เพื่อนำเสนอเนื้อหา Instrument Cluster บนจอแสดงผลทางกายภาพระยะไกล
อีกทางหนึ่ง รหัสนี้อาจส่งผ่าน 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 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(..)
เพื่อดึงข้อมูลชื่อแพ็กเกจของเจ้าของปัจจุบันของประเภทแอปพลิเคชันที่กำหนดซึ่งอยู่ในโฟกัส วิธีนี้อาจส่งคืนชื่อแพ็กเกจมากกว่าหนึ่งชื่อหากเจ้าของปัจจุบันใช้คุณลักษณะ 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 จัดเตรียมแอปพลิเคชันตัวอย่างที่ใช้ Navigation State API
เมื่อต้องการเรียกใช้แอปพลิเคชันตัวอย่างนี้:
- สร้างและแฟลช Android Auto บน HU ที่รองรับ ใช้คำแนะนำในการสร้างและการกะพริบของ Android สำหรับอุปกรณ์ของคุณโดยเฉพาะ สำหรับคำแนะนำ โปรดดูที่ การใช้บอร์ดอ้างอิง
- เชื่อมต่อจอแสดงผลรองทางกายภาพกับ HU (หากรองรับ) หรือเปิด HU รองเสมือน:
- เลือก โหมดนักพัฒนาซอฟต์แวร์ ในแอปการตั้งค่า
- ไปที่ การตั้งค่า > ระบบ > ขั้นสูง > ตัวเลือกสำหรับนักพัฒนา > จำลองจอแสดงผลรอง
- รีบูต HU บริการ ClusterRenderingService เชื่อมต่อกับจอแสดงผลรอง
- วิธีเปิดแอป KitchenSink:
- เปิดลิ้นชัก
- ไปที่ สถาบัน กลุ่ม .
- คลิก เริ่มข้อมูลเมตา
KitchenSink ขอโฟกัสการนำทาง ซึ่งสั่งให้บริการ DirectRenderingCluster
แสดงอินเทอร์เฟซผู้ใช้จำลองบน Instrument Cluster