แผงหน้าปัด

ใช้ 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 .

โฟลว์ข้อมูลสถานะการนำทางตามลำดับนี้:

  1. CarService เริ่มต้น InstrumentClusterRenderingService
  2. ในระหว่างการเริ่มต้น InstrumentClusterRenderingService จะอัปเดต CarService ด้วย:
    1. คุณสมบัติการแสดงคลัสเตอร์เครื่องมือ เช่น ขอบเขตที่ไม่คลุมเครือ (ดูรายละเอียดเพิ่มเติมเกี่ยวกับขอบเขตที่ไม่คลุมเครือในภายหลัง)
    2. ตัวเลือกกิจกรรมที่จำเป็นในการเปิดกิจกรรมภายในจอแสดงผลของแผงหน้าปัด (ดูรายละเอียดเพิ่มเติมที่ ActivityOptions
  3. แอปการนำทาง (เช่น Google Maps สำหรับ Android Automotive หรือแอปแผนที่ใดๆ ที่มีสิทธิ์ที่จำเป็น):
    1. รับ CarAppFocusManager โดยใช้คลาส Car จาก car-lib
    2. ก่อนเริ่มเส้นทางแบบเลี้ยวต่อเลี้ยว ให้โทรไปที่ CarAppFocusManager.requestFocus() เพื่อส่ง CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION เป็นพารามิเตอร์ appType
  4. CarAppFocusManager แจ้งคำขอนี้ไปยัง CarService หากได้รับอนุญาต CarService ตรวจสอบแพ็คเกจแอพการนำทางและค้นหากิจกรรมที่มีหมวดหมู่ android.car.cluster.NAVIGATION
  5. หากพบ แอปการนำทางจะใช้ 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

เพื่อสร้างบริการ:

  1. เขียนคลาสที่ขยายจาก InstrumentClusterRenderingService แล้วเพิ่มรายการที่เกี่ยวข้องลงในไฟล์ AndroidManifest.xml ของคุณ คลาสนี้ควบคุมการแสดงผลของ Instrument Cluster และสามารถ ( ทางเลือก ) เรนเดอร์ข้อมูล Navigation State API
  2. ระหว่าง onCreate() ให้ใช้บริการนี้เพื่อเริ่มต้นการสื่อสารกับฮาร์ดแวร์การแสดงผล ตัวเลือกได้แก่:
    • กำหนดจอแสดงผลรองที่จะใช้สำหรับแผงหน้าปัด
    • สร้างจอแสดงผลเสมือนเพื่อให้แอป Instrument Cluster แสดงผลและส่งภาพที่แสดงผลไปยังหน่วยภายนอก (โดยใช้รูปแบบการสตรีมวิดีโอ เช่น H.264)
  3. เมื่อการแสดงผลที่ระบุข้างต้นพร้อม บริการนี้ต้องเรียก InstrumentClusterRenderingService#setClusterActivityLaunchOptions() เพื่อกำหนด ActivityOptions ที่แน่นอนซึ่งต้องใช้เพื่อแสดงกิจกรรมบน Instrument Cluster ใช้พารามิเตอร์เหล่านี้:
    • หมวดหมู่. CarInstrumentClusterManager#CATEGORY_NAVIGATION
    • ActivityOptions. อินสแตนซ์ ActivityOptions ที่สามารถใช้เพื่อเปิดกิจกรรมในคลัสเตอร์เครื่องมือ ตัวอย่างเช่น จากตัวอย่างการใช้งานคลัสเตอร์เครื่องมือบน AOSP:
      getService().setClusterActivityLaunchOptions(
         CATEGORY_NAVIGATION,
         ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
      
  4. เมื่อ Instrument Cluster พร้อมที่จะแสดงกิจกรรม บริการนี้ต้องเรียกใช้ InstrumentClusterRenderingService#setClusterActivityState() ใช้พารามิเตอร์เหล่านี้:
    • category CarInstrumentClusterManager#CATEGORY_NAVIGATION
    • state Bundle ที่สร้างด้วย ClusterActivityState อย่าลืมให้ข้อมูลต่อไปนี้:
      • visible ระบุกลุ่มเครื่องมือที่มองเห็นได้และพร้อมที่จะแสดงเนื้อหา
      • unobscuredBounds สี่เหลี่ยมผืนผ้าที่กำหนดพื้นที่ภายในจอแสดงผล Instrument Cluster ซึ่งแสดงเนื้อหาได้อย่างปลอดภัย ตัวอย่างเช่น พื้นที่ที่ครอบคลุมโดยแป้นหมุนและมาตรวัด
  5. แทนที่เมธอด 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

ในการรันแอปพลิเคชันตัวอย่างนี้:

  1. สร้างและแฟลช Android Auto บน HU ที่รองรับ ใช้การสร้าง Android และคำแนะนำแบบกะพริบเฉพาะสำหรับอุปกรณ์ของคุณ สำหรับคำแนะนำ โปรดดู การใช้บอร์ดอ้างอิง
  2. เชื่อมต่อจอแสดงผลรองจริงกับ HU (หากรองรับ) หรือเปิด HU สำรองเสมือน:
    1. เลือก โหมดนักพัฒนาซอฟต์แวร์ ในแอปการตั้งค่า
    2. ไปที่ การตั้งค่า > ระบบ > ขั้นสูง > ตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ > จำลองจอภาพรอง
  3. รีบูตเครื่อง HU บริการ ClusterRenderingService เชื่อมต่อกับจอแสดงผลรอง
  4. ในการเปิดแอป KitchenSink:
    1. เปิดลิ้นชัก
    2. ไปที่ สถาบัน คลัสเตอร์
    3. คลิก เริ่มเมตาดาต้า

KitchenSink ขอโฟกัส NAVIGATION ซึ่งสั่งให้บริการ DirectRenderingCluster แสดงอินเทอร์เฟซผู้ใช้ที่จำลองขึ้นบน Instrument Cluster