消費汽車駕駛狀態和UX限制

本頁介紹了應用程式如何優雅地過渡到分散注意力優化 (DO) 使用者介面。它描述瞭如何消費汽車的行駛狀態以及相應的使用者體驗限制。有關汽車用戶體驗 (UX) 限制的更多信息,請參閱汽車用戶體驗限制,其中詳細介紹了停車、怠速和移動三種駕駛狀態。

觀眾

此內容是為那些想要設計適應汽車駕駛狀態變化和相應的用戶體驗限制的應用程式的人提供的。

技術細節

汽車駕駛狀態管理器

汽車的駕駛狀態(停車、怠速或移動)源自於車輛硬體抽象層 (VHAL) 提供的感測器值。基本感測器訊息,例如車速和當前檔位選擇,用於得出車輛當前的行駛狀態。

CarDrivingStateEvent

它提供@SystemApis,這意味著只有平台內部、捆綁的APK(例如SysUI或設定)和特權APK(例如)GMSCore可以存取API。 API 受特定駕駛狀態android.car.permission.CAR_DRIVING_STATE的權限保護。需要存取駕駛狀態資訊的用戶端必須請求此許可。

CarUx限制管理器

那些根據駕駛狀態顯示使用者介面的應用程式必須偵聽CarUxRestrictionsManager ,它抽象化了從駕駛狀態到 UX 限制的映射,以便應用程式不需要根據不同的市場安全要求進行調整。

注意:這些活動必須標記為分散注意力優化,如駕駛員分散注意力指南中所述。如果活動沒有相應標記,它們就會被阻止。

相反,應用程式監視 CarUxRestrictionsManager 公開的限制,而不是 CarDrivingStateManager 公開的與使用者介面或使用者體驗相關的任何內容的絕對駕駛狀態。

程式碼範例

以下範例程式碼說明了應用程式如何監控 UX 限制:

  1. 導入汽車庫包:
    import android.car.Car;
    /* For CarUxRestrictions */
    import android.car.drivingstate.CarUxRestrictions;
    import android.car.drivingstate.CarUxRestrictionsManager;
    
  2. 實作CarUxRestrictionManager.OnUxRestrictionsChangedListener ( mUxRChangeListener )。當向CarUxRestrictionsManager註冊後,當 UX 限制發生變更時,將呼叫此偵聽器。根據需要處理限制變更以優化分心:
    @Nullable private CarUxRestrictionsManager mCarUxRestrictionsManager;
    private CarUxRestrictions mCurrentUxRestrictions;
    
    /* Implement the onUxRestrictionsChangedListener interface */
    private CarUxRestrictionsManager.OnUxRestrictionsChangedListener mUxrChangeListener =
                new CarUxRestrictionsManager.OnUxRestrictionsChangedListener()
        {
            @Override
            public void onUxRestrictionsChanged(CarUxRestrictions carUxRestrictions) {
            mCurrentUxRestrictions = carUxRestrictions;
            /* Handle the new restrictions */
            handleUxRestrictionsChanged(carUxRestrictions);
            }
        };
      
  3. 呼叫汽車 API 建立名為 mCar 的汽車實例並連接到汽車服務:
    mCar = Car.createCar(context);
    if (mCar == null) {
    // handle car connection error
    }
    
  4. 呼叫mCar.getCarManager() - mCarUxRestrictionsManager取得CarUxRestrictionsManager
    CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
    mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
    
  5. 若要使用CarUxRestrictionsManager註冊在上述步驟 2 中實作的mUxRChangeListener ,請呼叫mCarUxRestrictionsManager.registerListener()
    mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
    mUxrChangeListener.onUxRestrictionsChanged(
    mCarUxRestrictionsManager.getCurrentCarUxRestrictions());
    

完成的範例程式碼區塊(在步驟 3 到步驟 5 中建立)會導致偵聽器在磁碟機狀態變更時接收限制變更:

mCar = Car.createCar(context);
if (mCar == null) {
// handle car connection error
}

CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
mCar.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);

mCarUxRestrictionsManager.registerListener(mUxrChangeListener);
mUxrChangeListener.onUxRestrictionsChanged(
mCarUxRestrictionsManager.getCurrentCarUxRestrictions());

CarUx限制

CarUxRestrictions物件提供兩種類型的資訊:

  1. 目前是否有優化干擾的要求?
  2. 如果是這樣,目前有哪些限制?

當從getCurrentUxRestrictions()或偵聽器回呼獲取CarUxRestrictions時,應用程式現在可以使用isRequiresDistractionOptimization() API 來決定是否需要 Distraction Optimized。如果返回false ,則無需進行分心優化,應用程式可以安全地運行任何活動。

如果需要最佳化,請使用getActiveRestrictions() API 取得現有的限制集。此 API 傳回一個int ,它是當前有效的所有限制的位元遮罩。目前通知的一組限制列在CarUxRestrictions下。

注意:預計在不久的將來會對一系列限制進行細微更改。

例如,如果應用程式想要確定是否存在播放影片的限制,則在取得 CarUxRestrictions 物件後,應用程式必須檢查該限制:

int activeUxR = mCurrentCarUxRestrictions.getActiveRestrictions();
if ((activeUxR & CarUxRestrictions.UX_RESTRICTIONS_NO_VIDEO) != 0) {
      handleStopPlayingVideo();
}

駕駛狀態

CarDrivingStateManager 呈現車輛的實際駕駛狀態(停車、怠速或移動)。 CarDrivingStateManager API 的呼叫方式與 CarUxRestrictionsManager 類似。應用程式可以註冊偵聽器或取得當前的駕駛狀態。駕駛狀態以 CarDrivingStateEvent 返回。

CarDrivingStateEvent

變更時,會使用新的CarDrivingStateEvent來呼叫onDrivingStateChanged()方法。

import android.car.Car;
/* For CarDrivingState */
import android.car.drivingstate.CarDrivingStateEvent;
import android.car.drivingstate.CarDrivingStateManager;

mDrivingStateManager = (CarDrivingStateManager) mCar.getCarManager(
       Car.CAR_DRIVING_STATE_SERVICE);
/* Register the listener (implemented below) */
mDrivingStateManager.registerListener(mDrivingStateEventListener);
/* While we wait for a change to be notified, query the current state */
mDrivingStateEvent = mDrivingStateManager.getCurrentCarDrivingState();

private final CarDrivingStateManager.CarDrivingStateEventListener
mDrivingStateEventListener =
       new CarDrivingStateManager.CarDrivingStateEventListener() {
   @Override
   public void onDrivingStateChanged(CarDrivingStateEvent event) {
       mDrivingStateEvent = event;
       /* handle the state change accordingly */
       handleDrivingStateChange();
   }
};

測試

您可以模仿檔位和速度的變化來改變駕駛狀態。使用 ADB shell 指令注入車輛事件。這對於開發和測試非常有用。

模擬駕駛事件:

  1. 將速度設定為 0:
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 0
    
  2. 將檔位設定為「停車」(模擬指向「停車」的 CarDrivingStateEvent):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 4
    
  3. 將檔位設為 Drive,速度仍為 0(模擬指向 IDLING 的 CarDrivingStateEvent):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11400400 8
    
  4. 將速度設定為每秒 30 公尺(模擬指向 MOVING 的 CarDrivingStateEvent):
    adb shell dumpsys activity service com.android.car inject-vhal-event 0x11600207 30