ดำเนินการตามคำสั่ง

หน้านี้จะอธิบายวิธีดำเนินการตามคำสั่งด้วยการโต้ตอบด้วยเสียง

ทำตามคำสั่งสื่อ

คำสั่งเกี่ยวกับสื่อจะแบ่งออกเป็น 3 กลุ่มดังนี้

  • แหล่งที่มาสื่อภายนอก (เช่น Spotify ที่ติดตั้งใน AAOS)
  • แหล่งที่มาของสื่อแบ็กเอนด์ (เช่น เพลงที่สตรีมผ่าน VIA)
  • แหล่งที่มาสื่อในท้องถิ่น (เช่น วิทยุในรถยนต์)

จัดการคำสั่งของแหล่งที่มาสื่อภายนอก

แหล่งที่มาสื่อภายนอกหมายถึงแอป Android ที่รองรับ MediaSessionCompat และ MediaBrowseCompat API (โปรดดูสร้างแอปสื่อสำหรับ เพื่อดูคำอธิบายโดยละเอียดเกี่ยวกับการใช้ API เหล่านี้)

ข้อสำคัญ: เพื่อให้แอป Assistant เชื่อมต่อกับ MediaBrowseService ของแอปสื่อทั้งหมดที่ติดตั้งไว้ใน ต้องมีลักษณะดังนี้

  1. ได้รับการติดตั้งเป็นระบบที่ลงนาม (ดูหลักเกณฑ์การพัฒนาแอปพลิเคชันสื่อสำหรับ AAOS และโค้ด PackageValidator ตัวอย่าง)
  2. ถือสิทธิ์ของระบบ android.permission.MEDIA_CONTENT_CONTROL รายการ สิทธิ์ (โปรดดูให้สิทธิ์ สิทธิ์ของระบบ)

นอกเหนือจาก MediaBrowserCompat และ MediaControllerCompat AAOS มีฟีเจอร์ต่อไปนี้

  • CarMediaService ให้ข้อมูลแบบรวมศูนย์เกี่ยวกับแหล่งที่มาของสื่อที่เลือกในปัจจุบัน นี่คือ ยังใช้เพื่อกลับสู่แหล่งที่มาสื่อที่เล่นก่อนหน้านี้อีกครั้งหลังจากรีสตาร์ทรถ
  • car-media-common มอบวิธีที่สะดวกในการแสดง ติดต่อ และโต้ตอบกัน กับแอปสื่อ

ด้านล่างนี้เป็นหลักเกณฑ์เฉพาะสำหรับการใช้งานการโต้ตอบด้วยเสียงทั่วไป คำสั่ง

ดูรายการแหล่งที่มาของสื่อที่ติดตั้งไว้

คุณสามารถตรวจหาแหล่งที่มาของสื่อได้โดยใช้ PackageManager และการกรองบริการที่ตรงกับ MediaBrowserService.SERVICE_INTERFACE ในรถบางรุ่น อาจมีการติดตั้งบริการสื่อเบราว์เซอร์แบบพิเศษ ที่ควรยกเว้น ตัวอย่างตรรกะนี้

private Map<String, MediaSource> getAvailableMediaSources() {
    List<String> customMediaServices =
        Arrays.asList(mContext.getResources()
            .getStringArray(R.array.custom_media_packages));
    List<ResolveInfo> mediaServices = mPackageManager.queryIntentServices(
            new Intent(MediaBrowserService.SERVICE_INTERFACE),
            PackageManager.GET_RESOLVED_FILTER);
    Map<String, MediaSource> result = new HashMap<>();
    for (ResolveInfo info : mediaServices) {
        String packageName = info.serviceInfo.packageName;
        if (customMediaServices.contains(packageName)) {
            // Custom media sources should be ignored, as they might have a
            // specialized handling (e.g., radio).
            continue;
        }
        String className = info.serviceInfo.name;
        ComponentName componentName = new ComponentName(packageName,
            className);
        MediaSource source = MediaSource.create(mContext, componentName);
        result.put(source.getDisplayName().toString().toLowerCase(),
            source);
    }
    return result;
}

โปรดทราบว่าอาจมีการติดตั้งหรือถอนการติดตั้งแหล่งที่มาของสื่อได้ทุกเมื่อ ใน เราขอแนะนำให้ใช้ BroadcastReceiver เพื่อรักษารายการให้ถูกต้องอยู่เสมอ สำหรับการดำเนินการ Intent ACTION_PACKAGE_ADDED ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REPLACED และ ACTION_PACKAGE_REMOVED

เชื่อมต่อกับแหล่งที่มาของสื่อที่เล่นอยู่

CarMediaService ระบุวิธีการรับแหล่งที่มาสื่อที่เลือกในปัจจุบัน และเมื่อสื่อนี้ การเปลี่ยนแปลงที่มา การเปลี่ยนแปลงเหล่านี้อาจเกิดขึ้นเนื่องจากผู้ใช้โต้ตอบกับ UI โดยตรง หรือเนื่องจากการใช้ปุ่มฮาร์ดแวร์ในรถ ในทางกลับกัน ไลบรารีที่ใช้สื่อทั่วไปในรถยนต์ (car-media-commonไลบรารี) ให้วิธีที่สะดวกในการเชื่อมต่อกับสื่อหนึ่งๆ แหล่งที่มา ต่อไปนี้เป็นตัวอย่างสั้นๆ เกี่ยวกับวิธีเชื่อมต่อกับเครือข่ายที่เลือกในปัจจุบัน แอปสื่อ:

public class MediaActuator implements
        MediaBrowserConnector.onConnectedBrowserChanged {
    private final Car mCar;
    private CarMediaManager mCarMediaManager;
    private MediaBrowserConnector mBrowserConnector;

    …

    public void initialize(Context context) {
        mCar = Car.createCar(context);
        mBrowserConnector = new MediaBrowserConnector(context, this);
        mCarMediaManager = (CarMediaManager)
            mCar.getCarManager(Car.CAR_MEDIA_SERVICE);
        mBrowserConnector.connectTo(mCarMediaManager.getMediaSource());
        …
    }

    @Override
    public void onConnectedBrowserChanged(
            @Nullable MediaBrowserCompat browser) {
        // TODO: Handle connected/disconnected browser
    }

    …
}

ควบคุมการเล่นของแหล่งที่มาของสื่อที่เล่นอยู่

เมื่อมี MediaBrowserCompat ที่เชื่อมต่ออยู่ การส่งการขนส่งทำได้ง่าย คำสั่งควบคุมไปยังแอปเป้าหมาย โดยดูแบบง่าย ตัวอย่าง:

public class MediaActuator …  {
    …
    private MediaControllerCompat mMediaController;

    @Override
    public void onConnectedBrowserChanged(
            @Nullable MediaBrowserCompat browser) {
        if (browser != null && browser.isConnected()) {
            mMediaController = new MediaControllerCompat(mContext,
                browser.getSessionToken());
        } else {
            mMediaController = null;
        }
    }

    private boolean playSongOnCurrentSource(String song) {
        if (mMediaController == null) {
            // No source selected.
            return false;
        }
        MediaControllerCompat.TransportControls controls =
            mMediaController.getTransportControls();
        PlaybackStateCompat state = controller.getPlaybackState();
        if (state == null || ((state.getActions() &
                PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH) == 0)) {
            // Source can't play from search
            return false;
        }
        controls.playFromSearch(query, null);
        return true;
    }

    …
}

จัดการคำสั่งของแหล่งที่มาของสื่อในเครื่อง (วิทยุ เครื่องเล่น CD บลูทูธ USB)

แหล่งที่มาของสื่อในท้องถิ่นแสดงฟังก์ชันการทำงานของระบบโดยใช้ MediaSession และ MediaBrowse API ตามรายละเอียดด้านบน เพื่อรองรับคุณลักษณะเฉพาะ ฮาร์ดแวร์แต่ละประเภท บริการ MediaBrowse เหล่านี้ใช้ข้อกำหนดเฉพาะในการจัดระเบียบ ข้อมูลและคำสั่งสื่อของตน

จัดการวิทยุ

โดยจะระบุ Radio MediaBrowseService ได้ด้วย ACTION_PLAY_BROADCASTRADIO Intent การควบคุมการเล่นและการเรียกดูสื่อจะเป็นไปตามการควบคุมการเล่นและการเรียกดูสื่อ ที่อธิบายไว้ในหัวข้อติดตั้งวิทยุ AAOS เสนอ car-broadcastradio-support ไลบรารีที่มีค่าคงที่และวิธีการเพื่อช่วย OEM สร้าง MediaBrowseService การใช้งานบริการวิทยุของตนเองที่เป็นไปตามโปรโตคอลที่ระบุไว้ และให้การสนับสนุนสำหรับแอปที่ใช้โครงสร้างการเรียกดู (เช่น VIA)

จัดการอินพุตเสริม, เสียง CD และสื่อ USB

ไม่มีการติดตั้งใช้งานเริ่มต้นของแหล่งที่มาสื่อเหล่านี้ในฐานะที่เป็นส่วนหนึ่งของ AOSP แนวทางที่แนะนำมีดังนี้

  • ให้ OEM ใช้บริการสื่อสำหรับแต่ละราย โปรดดูรายละเอียดที่หัวข้อสร้างแอปสื่อสำหรับรถยนต์
  • การใช้งาน MediaBrowseService เหล่านี้จะได้รับการระบุและตอบสนองด้วยความตั้งใจ การดำเนินการที่ระบุไว้ใน General Play Intents
  • บริการเหล่านี้จะแสดงโครงสร้างการเรียกดูตามหลักเกณฑ์ที่อธิบายไว้ ที่แหล่งข้อมูลประเภทอื่นๆ

จัดการบลูทูธ

เนื้อหาสื่อบลูทูธจะแสดงผ่านโปรไฟล์บลูทูธ AVRCP ใน AAOS ประกอบด้วย การใช้งาน MediaBrowserService และ MediaSession ที่แยก รายละเอียดการสื่อสาร (ดูแพ็กเกจ/แอป/บลูทูธ)

โครงสร้างแผนผังสื่อของเบราว์เซอร์ที่เกี่ยวข้องจะกำหนดไว้ที่ BrowseTree คุณจะส่งคำสั่งควบคุมการเล่นได้เช่นเดียวกับแอปอื่นๆ โดยใช้การใช้งาน MediaSession

จัดการคำสั่งสตรีมมิงสื่อ

ในการใช้สตรีมมิงสื่อฝั่งเซิร์ฟเวอร์ VIA ต้องเป็นตัวเอง แหล่งที่มาของสื่อ โดยใช้ MediaBrowse และ MediaSession API โปรดดู สร้างแอปสื่อ สำหรับรถยนต์ การใช้ API เหล่านี้จะทำให้แอปควบคุมด้วยเสียงทำสิ่งต่อไปนี้ได้ (และอื่นๆ):

  • มีส่วนร่วมในการเลือกแหล่งที่มาของสื่อได้อย่างราบรื่น
  • กลับมาทำงานอีกครั้งโดยอัตโนมัติหลังจากรีสตาร์ทรถ
  • ให้การควบคุมการเล่นและการท่องเว็บโดยใช้ UI ของ Media Center
  • รับเหตุการณ์เกี่ยวกับปุ่มสื่อฮาร์ดแวร์มาตรฐาน

ไม่มีวิธีมาตรฐานในการโต้ตอบกับแอปนำทางทั้งหมด สำหรับการผสานรวมกับ Google Maps โปรดดูที่ Google Maps for Android Automotive Intent สำหรับการผสานรวมกับ โปรดติดต่อนักพัฒนาแอปโดยตรง ก่อนการเปิดตัว แอป (รวมถึง Google Maps) เพื่อยืนยันว่า Intent นั้น ได้รับการแก้ไขแล้ว (ดูความตั้งใจ คำขอ) ซึ่งเป็นโอกาสในการแจ้งให้ผู้ใช้ทราบในกรณีที่ แอปเป้าหมายไม่พร้อมใช้งาน

ดำเนินการตามคำสั่งของรถ

คุณสามารถเข้าถึงพร็อพเพอร์ตี้ยานพาหนะสำหรับทั้งการอ่านและเขียนได้ผ่านทาง CarPropertyManager อธิบายประเภทพร็อพเพอร์ตี้ของยานพาหนะ การใช้งาน และรายละเอียดอื่นๆ ในพร็อพเพอร์ตี้ และการกำหนดค่าของคุณ หากต้องการคำอธิบายที่ถูกต้องเกี่ยวกับที่พักที่รองรับ โดย Android คุณควรอ้างอิง hardware/interfaces/automotive/vehicle/2.0/types.hal โดยตรง VehicleProperty enum ที่กำหนดไว้มีทั้งคุณสมบัติ ข้อมูล ทั้งแบบมาตรฐานและเฉพาะผู้ให้บริการ ประเภท โหมดเปลี่ยน หน่วย และคำจำกัดความการเข้าถึงแบบอ่าน/เขียน

หากต้องการเข้าถึงค่าคงที่เหล่านี้จาก Java คุณสามารถใช้ VehiclePropertyIds และคลาสที่ใช้ร่วมกัน พร็อพเพอร์ตี้แต่ละรายการมีสิทธิ์ Android ที่แตกต่างกันซึ่งควบคุมสิทธิ์ของตน สิทธิ์การเข้าถึง มีการประกาศสิทธิ์เหล่านี้ใน CarService ไฟล์ Manifest และการแมประหว่างพร็อพเพอร์ตี้และสิทธิ์ที่อธิบายไว้ ใน VehiclePropertyIds Javadoc และบังคับใช้ใน PropertyHalServiceIds

อ่านข้อมูลยานพาหนะ

ตัวอย่างวิธีการอ่านความเร็วของยานพาหนะมีดังนี้

public class CarActuator ... {
    private final Car mCar;
    private final CarPropertyManager mCarPropertyManager;
    private final TextToSpeech mTTS;

    /** Global VHAL area id */
    public static final int GLOBAL_AREA_ID = 0;

    public CarActuator(Context context, TextToSpeech tts) {
        mCar = Car.createCar(context);
        mCarPropertyManager = (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE);
        mTTS = tts;
        ...
    }

    @Nullable
    private void getSpeedInMetersPerSecond() {
        if (!mCarPropertyManager.isPropertyAvailable(VehiclePropertyIds.PERF_VEHICLE_SPEED,
                GLOBAL_AREA_ID)) {
            mTTS.speak("I'm sorry, but I can't read the speed of this vehicle");
            return;
        }
        // Data type and unit can be found in
        // automotive/vehicle/2.0/types.hal
        float speedInMps = mCarPropertyManager.getFloatProperty(
                VehiclePropertyIds.PERF_VEHICLE_SPEED, GLOBAL_AREA_ID);
        int speedInMph = (int)(speedInMetersPerSecond * 2.23694f);
        mTTS.speak(String.format("Sure. Your current speed is %d miles "
                + "per hour", speedInUserUnit);
    }

    ...
}

ตั้งค่าพร็อพเพอร์ตี้ยานพาหนะ

ตัวอย่างแสดงวิธีเปิดและปิดเครื่องปรับอากาศด้านหน้า

public class CarActuator … {
    …

    private void changeFrontAC(boolean turnOn) {
        List<CarPropertyConfig> configs = mCarPropertyManager
                .getPropertyList(new ArraySet<>(Arrays.asList(
                    VehiclePropertyIds.HVAC_AC_ON)));
        if (configs == null || configs.size() != 1) {
            mTTS.speak("I'm sorry, but I can't control the AC of your vehicle");
            return;
        }

        // Find the front area Ids for the AC property.
        int[] areaIds = configs.get(0).getAreaIds();
        List<Integer> areasToChange = new ArrayList<>();
        for (int areaId : areaIds) {
            if ((areaId & (VehicleAreaSeat.SEAT_ROW_1_CENTER
                        | VehicleAreaSeat.SEAT_ROW_1_LEFT
                        | VehicleAreaSeat.SEAT_ROW_1_RIGHT)) == 0) {
                continue;
            }
            boolean isACInAreaAlreadyOn = mCarPropertyManager
                    .getBooleanProperty(VehiclePropertyIds.HVAC_AC_ON, areaId);
            if ((!isACInAreaAlreadyOn && turnOn) || (isACInAreaAlreadyOn && !turnOn)) {
                areasToChange.add(areaId);
            }
        }
        if (areasToChange.isEmpty()) {
            mTTS.speak(String.format("The AC is already %s", turnOn ? "on" : "off"));
            return;
        }

        for (int areaId : areasToChange) {
            mCarPropertyManager.setBooleanProperty(
                VehiclePropertyIds.HVAC_AC_ON, areaId, turnOn);
        }
        mTTS.speak(String.format("Okay, I'm turning your front AC %s",
            turnOn ? "on" : "off"));
    }

    …
}

ดำเนินการตามคำสั่งการสื่อสาร

จัดการคำสั่งการรับส่งข้อความ

VIA ต้องจัดการข้อความขาเข้าหลังจาก "แตะเพื่ออ่าน" อธิบายขั้นตอนแล้ว ในผู้ช่วยเสียง แตะเพื่ออ่าน ซึ่งสามารถจัดการการส่งการตอบกลับกลับไปยังผู้ส่งข้อความขาเข้าได้ นอกจากนี้ VIA ยังใช้ SmsManager ได้ด้วย (เป็นส่วนหนึ่งของ android.telephony ) เพื่อเขียนและส่งข้อความ SMS โดยตรงจากรถหรือผ่านบลูทูธ

จัดการคำสั่งการโทร

ในทำนองเดียวกัน VIA สามารถใช้ TelephonyManager เพื่อโทรออกและโทรหาหมายเลขข้อความเสียงของผู้ใช้ ในกรณีเหล่านี้ VIA จะโต้ตอบกับสแต็กโทรศัพท์โดยตรงหรือโต้ตอบกับแป้นโทรศัพท์รถยนต์ แอป ไม่ว่าในกรณีใดก็ตาม แอปแป้นโทรศัพท์ในรถยนต์ควรเป็นแอปที่แสดง UI ที่เกี่ยวข้องกับการโทรด้วยเสียงแก่ผู้ใช้

ทำตามคำสั่งอื่นๆ

สำหรับรายการจุดผสานรวมอื่นๆ ที่เป็นไปได้ระหว่าง VIA และ ให้ตรวจสอบรายการ Intent ของ Android ที่รู้จักกันดี หลายหน้า คำสั่งของผู้ใช้จะแก้ไขได้จากฝั่งเซิร์ฟเวอร์ (เช่น การอ่าน อีเมลของผู้ใช้และกิจกรรมในปฏิทิน) และไม่ต้องมีการโต้ตอบกับระบบ นอกเหนือจากการโต้ตอบด้วยเสียงเอง

การดำเนินการแบบสมจริง (แสดงเนื้อหาภาพ)

ที่ช่วยส่งเสริมการกระทำหรือความเข้าใจของผู้ใช้ VIA สามารถมอบ เนื้อหาเสริมที่มองเห็นได้บนหน้าจอรถ เพื่อลดสิ่งรบกวนผู้ขับขี่ ทำให้เนื้อหานั้นเรียบง่าย กระชับ และนำไปใช้ได้จริง สำหรับรายละเอียดเกี่ยวกับหลักเกณฑ์ UI/UX เกี่ยวกับการดำเนินการที่สมจริง โปรดดู ผู้ช่วยที่โหลดไว้ล่วงหน้า: คำแนะนำสำหรับ UX

เพื่อให้สามารถปรับแต่งได้และมีความสอดคล้องกับ ส่วนที่เหลือของการออกแบบระบบเครื่องเสียง (HU) VIA ควรใช้ รถยนต์ UI Library สำหรับองค์ประกอบ UI ส่วนใหญ่ โปรดดูรายละเอียดที่หัวข้อ การปรับแต่ง