觸覺回饋架構的 UX 基礎

所有與觸覺回饋相關的 Android 架構改良項目,都是根據一組與時俱進的使用者體驗原則而開發。目前的原則包括以清晰的觸覺回饋取代震動,以及探索豐富的觸覺回饋

使用者體驗原則

圖 1. 目前的原則。

下表列出所有可用的觸覺回饋 API:

API 方法和常數 新增年份
android.view.HapticFeedbackConstants
  • CONTEXT_CLICK
  • CLOCK_TICK
  • VIRTUAL_KEY
  • KEYBOARD_TAP
  • LONG_PRESS
2016 年前
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY_RELEASE
2017 年 (Android 8)
  • CONFIRM
  • REJECT
  • GESTURE_START
  • GESTURE_END
2020 年 (Android 11)
android.View
  • performHapticFeedback()
2016 年前
android.os.Vibrator
  • vibrate()
  • hasVibrator()
2016 年前
  • hasAmplitudeControl()
2017 年 (Android 8)
  • areAllEffectsSupported()
  • areAllPrimitivesSupported()
  • areEffectsSupported()
  • arePrimitivesSupported()
2020 年 (Android 11)
android.os.VibrationEffect
  • createOneShot()
  • createWaveform()
2017 年 (Android 8)
  • EFFECT_TICK
  • EFFECT_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_DOUBLE_CLICK
  • createPredefined()
2019 年 (Android 10)
android.os.VibrationEffect.Composition
  • PRIMITIVE_TICK
  • PRIMITIVE_CLICK
  • addPrimitive()
  • compose()
2020 年 (Android 11)
android.media.AudioAttributes.Builder
  • setHapticChannelsMuted()
2019 年 (Android 10)

震動幅度較強

早在呼叫器和功能型手機時代,低品質但省電的偏心旋轉質量 (ERM)蜂鳴器震動就已用來取代靜音模式下的鈴聲。如果舊版硬體元件會發出惱人的巨大聲響,可能會產生低品質的觸覺回饋,進而損害觸覺體驗 (例如便宜或損壞的手機)。

清除觸覺回饋

清晰觸覺回饋支援離散狀態變更的感覺 (例如開機和關機程序期間的二進位變更)。由於「離散」功能指標的性質,系統會將清晰的觸覺回饋生成為單一實體 (例如每個輸入事件一個觸覺效果)。

Android 的目標是提供清晰的觸覺回饋,以強烈但銳利的感覺為主,而非震動或模糊的感覺。

為支援清晰觸覺回饋而建立的預先定義觸覺常數包括下列元素。

HapticFeedbackConstants

  • CLOCK_TICK
  • CONFIRM
  • CONTEXT_CLICK
  • GESTURE_END
  • GESTURE_START
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • KEYBOARD_TAP
  • LONG_PRESS
  • REJECT
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY
  • VIRTUAL_KEY_RELEASE

VibrationEffect

  • EFFECT_CLICK
  • EFFECT_DOUBLE_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_TICK

裝置製造商和開發人員建立共同知識,是提升 Android 生態系統中觸覺回饋整體品質的關鍵。請參閱基本檢查清單硬體評估CDD,進一步瞭解觸覺回饋實作方式。

按住後放開

圖 2. 按壓後放開。

豐富的觸覺回饋

豐富觸覺回饋是觸覺回饋技術的新興類別,可提供單一脈衝式效果以外的觸覺回饋。Android 的目標是支援豐富的觸覺回饋,並提供高度可組合性和可調整性,以及精細的精細度。Android 11 以下版本支援下列用途。

豐富的觸覺回饋

圖 3. 滑動紋理時提供豐富的觸覺回饋。

拖曳和滑動

圖 4. 拖曳和滑動。

用途 1:滑動紋理

如果手指在觸控表面上滑動時重複觸覺效果 (例如拖曳、滑動、探索具有虛擬觸覺紋理的表面),重複的觸覺效果最好是清晰且細微。

如果個別效果是嗡嗡聲而非清脆聲,則重複間隔可能會消失。結果會發出一次長長的震動,而不是多個不連續的訊號。

如果震幅不夠細微,重複的觸覺能量就會累積,導致最後的震動過於強烈。

為滑動和拖曳手勢導入表面觸覺紋理

HapticFeedbackConstants 中使用 CLOCK_TICKTEXT_HANDLE_MOVE。 這些常數會預先定義重複次數和振幅的特性。

建立自己的特效

如要製作自己的效果,請在 VibrationEffect.Composition 中,將 PRIMITIVE_CLICKPRIMITIVE_TICK 序列串連在一起,組成設計。 你可以使用 addPrimitive(int primitiveID, float scale, int delay) 調整重複次數和振幅比例的特徵。支援功能取決於 Vibrator HAL 介面CAP_COMPOSE_EFFECTS 功能。

用途 2:震動時間較長,且震動強度會逐漸增強

長震動是指從 0 轉換為目標振幅的平滑振幅震動。長震動可產生可察覺的注意力觸覺回饋。不過,在安靜的環境中,突然的長時間震動可能會嚇到使用者,而且通常會發出嗡嗡聲。如要產生更令人愉悅的長震動,請在長震動的開頭套用緩和效果。這會產生平滑的振幅轉換,並朝目標振幅建構。

套用「緩入」效果

  1. 使用 android.os.Vibrator.hasAmplitudeControl() 檢查振幅控制的硬體功能。

    • 結果必須為 true,才能產生振幅不同的緩和進入效果。
  2. 請使用 VibrationEffectcreateWaveform(timings[], amplitudes[], int repeat)

  3. 調整 timings[]amplitudes[] 系列,生成緩和進入曲線,如圖 5 所示。

長震動

圖 5. 震動幅度緩慢增加的曲線。

使用案例 3:音訊耦合觸覺回饋

音訊耦合觸覺是與音訊節奏耦合的觸覺模式,可吸引使用者注意。

音訊耦合觸覺回饋:優點

如要實作音訊耦合觸覺回饋,請將清晰的觸覺回饋與長震動結合。 清晰觸覺回饋功能會提供強烈但短暫的觸覺感受,傳達離散的節奏模式。搭配長震動提供的強烈刺激,可有效吸引使用者注意。

請務必考量感覺節奏模式。如果沒有節奏感,使用者會將觸覺感受視為隨機震動,並傾向於忽略。

音訊情侶

圖 6. 音訊耦合觸覺回饋範例。

音訊耦合觸覺回饋:導入提示

如要實作音訊耦合觸覺回饋,必須對音訊和觸覺通道的內容播放有基本瞭解。請注意以下幾點:

  • 使用 MediaPlayerSoundPool 類別。

    • OGG 格式的資產具有特殊中繼資料鍵 (ANDROID_HAPTIC 後接觸覺通道數),表示有觸覺資料,並可透過 MediaPlayerSoundPool 播放。
  • audio_policy_configuration.xml 中指出觸覺回饋和音訊播放的支援情形。

    • 使用具有觸覺回饋通道的輸出設定檔 AUDIO_CHANNEL_OUT_HAPTIC_A|B
    • 如果是具有觸覺通道的輸出串流,請注意,觸覺通道會以額外通道的形式出現在資料中。

    示例

    如果輸出串流的聲道遮罩如下所示:

    AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A

    這樣每個樣本看起來都會像這樣:

    AUDIO_LEFT_CHANNEL,AUDIO_RIGHT_CHANNEL,HAPTIC_CHANNEL_A

  • AudioAttributes.Builder( ).setHapticChannelsMuted(boolean muted) 變更為 false,即可播放觸覺回饋通道。

    • 根據預設,觸覺回饋通道會設為靜音 (true)。
    • 用途包括鈴聲和 UI 音效,並提供同步觸覺回饋。
  • Vibrator HAL 必須實作外部控制支援功能。

音訊耦合觸覺

圖 7. 實作音訊耦合觸覺回饋。

音訊耦合觸覺回饋:HapticGenerator

HapticGenerator 是 Android 12 推出的音效,可從音訊聲道產生觸覺回饋資料,並以音訊耦合觸覺回饋的形式即時播放。如圖 8 所示,效果會套用至 AudioTrack

觸覺效果產生器架構

圖 8. 觸覺效果產生器架構。

這張架構圖顯示 Haptic Generator 會在傳送至 Audio HAL 前,套用至傳入的使用者音訊串流。生成器會在 AudioMixer 分割音訊和觸覺回饋資料後套用,且會先於任何其他音訊效果套用,其輸出內容會覆寫串流中先前的任何觸覺回饋資料。

為確保觸覺產生器演算法能產生高品質的觸覺效果,請調整設定篩選器鏈結的參數,藉此調整裝置震動器馬達的產生演算法。本節將詳細說明這些參數,並說明如何根據硬體規格調整參數。

  • 帶通濾波器的共振頻率

    震動器共振頻率是指觸覺致動器達到最大輸出的頻率。這個參數會調整抗共振器,部分平坦化回應轉移函式,以取得更寬的頻寬。Android 架構會自動將這個值連結至 Vibrator HAL 方法 IVibrator.getResonantFrequency 的輸出內容。

    這個參數的預設值為 150 Hz。您可以在程式碼中修改這個值。

  • 慢速信封的正規化能力

    這個參數會決定部分正規化 (自動增益控制) 的指數。預設值為 -0.8,表示這個增益控制步驟會移除 80% 的動態範圍變化。你可以在程式碼中修改這項設定。

  • 帶阻濾波器的 Q 因子

    振動器品質因數 (Q 因數) 取決於兩個參數:

    • 零 Q,帶阻濾波器中零的品質因數,可部分抵銷共振

    • 極點 Q,帶阻濾波器中極點的品質因數

    這兩個值的比率會限制共振的抑制作用,以提升較低的頻率並擴大演算法回應。舉例來說,Zero Q 的預設值為 8,Pole Q 的預設值為 4,兩者比率為 2,因此共振抑制會限制為 2 倍 (6 dB)。Android 架構會將這兩個值連結至 Vibrator HAL 方法 IVibrator.getQFactor 的輸出內容。

    如果預設值未將裝置的馬達強度衰減納入考量,建議同時修改這兩個值,並同時增加或減少。零 Q 與極 Q 的比率應大於 1。你可以在程式碼中修改這項設定。

  • 失真轉角頻率

    低通濾波器會套用轉角頻率,抑制低階震動,並使用立方失真來強化高階震動。預設值為 300 Hz。你可以在程式碼中修改這個值。

  • 輸入增益和失真立方體閾值

    這些參數會套用至輸入波形的非線性失真濾波器,用來降低低頻信號的振幅,並提高高頻信號的振幅。

    • 輸入增益因子的預設值為 0.3
    • 立方體門檻的預設值為 0.1

    建議您一併修改這兩個值。您可以在程式碼中找到這些項目。

    如要進一步瞭解這個篩選器套用的函式,請參閱程式碼中的實作方式。

    如要進一步瞭解這兩個參數如何影響輸出內容,建議您繪製濾鏡的頻率響應,並觀察頻率響應如何隨著不同的參數值而變化。

  • 失真輸出增益

    這個參數可控制最終震動幅度。這是套用在軟限制器後的最終增益,可將震動幅度限制在 1 以下。預設值為 1.5,您可以在程式碼中修改這個值。

    如果震動幅度太小,請調高值。如果聽到致動器硬體發出喀喀聲,請降低值。