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