瞭解語音眼鏡的實體輸入路由

適用的 XR 裝置
本指南可協助您為這類 XR 裝置打造體驗。
語音眼鏡

在語音眼鏡上,系統會根據使用者意識 (而非視覺螢幕焦點) 轉送實體輸入內容 (例如觸控板手勢或按鈕)。由於使用者看不到使用者介面,系統會將實體輸入內容轉送至使用者正在感應或主動互動的任何應用程式體驗的投影活動。

系統如何判斷使用者是否知情

系統會監控下列哪些資料串流處於活躍狀態,藉此判斷使用者是否知情:

  • 音訊輸出串流:語音朗讀、音訊提示或媒體播放。
  • 麥克風錄音串流:持續接收語音指令或擷取使用者周遭環境的音訊。
  • 相機擷取串流:影片或相片串流。

部分資料串流是暫時性的,只會短暫保留使用者感知。例如,在導航路線時,以語音讀出使用者應採取的下一個轉彎。其他資料串流則沒有時間限制,只要持續進行,使用者就會一直知道。例如,使用無盡的隨機播放清單播放媒體。當暫時性資料串流中斷無限期資料串流時,會暫時吸引使用者注意。

並行和輸入焦點

使用者經常在語音眼鏡上同時執行多個應用程式體驗。例如,使用者可能會在聽音樂時,同時使用即時路況導航。在這種情況下,系統會指派「並行狀態」,並執行下列操作,將輸入焦點轉移至與音訊焦點相符的位置:

  • 繼續或停止應用程式的投影活動。
  • 將實體輸入內容轉送至前景投影活動。

這種做法有助於維持一致的使用者體驗。

讓系統重新啟動投影的活動

當應用程式獲得使用者注意時,尤其是預計活動在背景執行時,系統必須能夠恢復活動,並將實體輸入內容轉送至該活動。

為確保系統能重新啟動活動,請按照下列步驟操作:

  1. 建立待處理意圖:建立明確的 Intent,指向目標投影活動。將意圖包裝在 PendingIntent 中,並設定 FLAG_UPDATE_CURRENT 或 FLAG_IMMUTABLE,以維持安全且可預測的啟動行為:

    // Build an explicit Intent pointing to this projected activity and wrap it in a
    // PendingIntent so the system can relaunch it and route physical input to it.
    private val pendingIntent: PendingIntent by lazy {
        val intent = Intent(this, ProjectedInputFocusActivity::class.java)
    
        PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
    }

  2. 註冊輸入接收器:取得 ProjectedActivityCompat 的例項,並將 PendingIntent 傳遞至 setActivityAsInputReceiver,註冊為指定的輸入接收器。

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        lifecycleScope.launch {
            // Create or obtain the ProjectedActivityCompat instance
            val projectedActivity = ProjectedActivityCompat.create(this@ProjectedInputFocusActivity)
    
            // Register the PendingIntent as the designated input receiver
            projectedActivity.setActivityAsInputReceiver(pendingIntent)
        }

  3. 在清除時清除輸入接收器:當活動遭到刪除或不再需要接收實體輸入時,請清除輸入接收器,以免傳送過時的 PendingIntent,並避免記憶體流失。

    override fun onDestroy() {
        super.onDestroy()
        lifecycleScope.launch {
            val projectedActivity = ProjectedActivityCompat.create(this@ProjectedInputFocusActivity)
            projectedActivity.clearActivityAsInputReceiver()
        }
    }

瞭解輸入焦點如何在並行狀態之間轉移

為判斷哪個應用程式會接收輸入焦點,系統會評估使用中的資料串流,並根據下列並行狀態轉送輸入內容:

並行狀態 環境背景 系統行為和輸入焦點 範例

非並行

獨立投影活動正在進行中,沒有背景媒體工作階段。

即使在朗讀內容之間的靜音期間,輸入焦點也會完全轉移至投影的活動。

使用者執行運動應用程式。即使在靜音期間,觸控板輸入也會直接轉送至運動應用程式。

半並行

投影活動正在進行,但背景媒體工作階段處於暫停狀態。

在應用程式主動朗讀之間的靜音期間,輸入焦點預設為暫停的媒體遙控器。

使用者在音樂暫停時執行健身追蹤應用程式。在健身教練更新期間,輕觸觸控板會繼續播放音樂,而非觸發健身功能。

並行

雙重播放功能已啟用 (例如應用程式的語音通知會中斷或降低背景音樂音量)。

音訊焦點等於輸入焦點。

系統會在朗讀期間將輸入焦點導向投影活動,並在音訊串流結束時切換回媒體遙控器。

使用者正在聽音樂,導航應用程式發出語音指示。朗讀期間,導航應用程式會取得輸入焦點。朗讀完畢後,輸入焦點會移回媒體遙控器。

系統時間保護措施

系統提供下列保護措施,協助防止使用者意外輸入或發生非預期行為:

  • 新啟動投影活動的寬限期:為因應冷啟動資產載入或網路延遲,新啟動的投影活動會獲得短暫的寬限期,以便建立資料串流並讓使用者注意到,之後系統才會停止投影活動並移至背景。
  • 根據使用者感知轉移焦點:如果使用者感知因新的活動資料串流 (例如音訊朗讀) 而改變,系統會立即恢復投影活動,並將輸入焦點轉移至該活動。
  • 媒體播放期間的轉換緩衝區:在背景媒體播放期間,暫時性朗讀完成後,輸入焦點會暫時保留在投影活動上。緩衝期有助於防止意外輸入,例如使用者嘗試將朗讀內容設為靜音,卻略過音樂曲目。轉換緩衝區結束後,系統會停止應用程式的投影活動,並將輸入焦點轉送至媒體遙控器。
  • 閒置的投影活動會停止或暫停:系統會在幾分鐘後停止任何沒有有效資料串流的閒置投影活動 (或在暫停時暫時停止進行中的媒體輸出)。

輸入焦點轉換實務

如要瞭解輸入焦點如何在並行狀態之間轉換,請參考以下範例情境,其中導航應用程式提供即時路線指引:

情境 A:非並行 (閒置媒體)

在這種情況下,系統會將輸入內容轉送至導航應用程式,該應用程式在整個行程中都會感知使用者。

圖 1. 在這種非並行情境下,導航應用程式的輸入焦點會如何轉送。
  1. 使用者啟動導航,但背景未播放音樂。
  2. 導航應用程式會在語音眼鏡上啟動投影活動。
  3. 由於沒有任何媒體工作階段處於活動狀態,導航應用程式會在整個旅程中維持觸控板輸入焦點。
  4. 使用者動作:在朗讀期間輕觸螢幕,可將導航指示設為靜音。在無聲時輕觸,可能會重複上一個指令。

情境 B:半並行 (暫停媒體)

在這種情況下,只要導航應用程式未偵測到使用者,系統就會將輸入內容轉送至系統媒體遙控器。

圖 2. 在這種半並行情境中,導航應用程式的輸入焦點會如何轉送。
  1. 使用者在背景音樂暫停時啟動導航。
  2. 在朗讀之間的靜音期間,輸入焦點預設為媒體遙控器。
  3. 當導航應用程式說出「500 英尺後左轉」時,就會取得輸入焦點。
  4. 使用者動作:在朗讀期間輕觸螢幕,可能會將導航語音設為靜音。在靜音期間輕觸 ,即可繼續播放音樂。

情境 C:並行 (使用中的媒體)

在這種情況下,只要導航應用程式未偵測到使用者,系統就會將輸入內容轉送至系統媒體遙控器,而且每次導航應用程式讀出內容時,系統都會降低播放中媒體的音量。

圖 3. 在這種並行情境下,導航應用程式的輸入焦點會如何轉送。
  1. 使用者在音樂播放時啟動導航。
  2. 在朗讀指示時,系統會調低背景音訊,並將輸入焦點轉移至導航應用程式。
  3. 使用者動作:在朗讀期間輕觸螢幕,可能會將導航語音設為靜音。在靜音期間輕觸,可控制媒體播放 (暫停或繼續)。