Android 裝置上最常見的震動致動器是線性共振致動器 (LRAs)。LRAs 會模擬按鈕在玻璃表面上點擊的感受,而玻璃表面不會有任何反應。清晰的點擊回饋信號通常會持續 10 到 20 毫秒。這種感覺可讓使用者互動更自然。對於虛擬鍵盤,這項點擊回饋功能可加快輸入速度並減少錯誤。
LRAs 有幾個常見的共振頻率:
- 部分 LRAs 的共振頻率介於 200 到 300 Hz,這與人類皮膚對振動的敏感頻率相符。在這個頻率範圍內,震動的感覺通常被形容為平滑、尖銳和穿透。
- 其他型號的 LRAs 共振頻率較低,約為 150 Hz。這種感覺在質地上較為柔軟、飽滿 (在維度上)。
在兩種不同頻率下,相同的輸入電壓可能會產生不同的振動輸出幅度。頻率離 LRA 的諧振頻率越遠,振動幅度就越低。
特定裝置的觸覺回饋效果會同時使用震動致動器和驅動程式。搭載超速和主動煞車功能的觸覺感應驅動器,可縮短 LRAs 的升溫時間和振鈴時間,進而提供更靈敏且清晰的震動效果。
震動器輸出加速
頻率至輸出加速度對應 (FOAM) 會說明在特定振動頻率 (以赫茲為單位) 下,可達到的最大輸出加速度 (以 G 峰值為單位)。從 Android 16 (API 級別 36) 開始,平台會透過 VibratorFrequencyProfile
提供此對應的內建支援功能。您可以使用這個類別,搭配基本和進階包函 API,建立觸覺效果。
大多數 LRA 馬達的 FOAM 只有一個峰值,通常位於共振頻率附近。加速度通常會隨著頻率偏離此範圍而以指數方式降低。曲線可能不對稱,且可能會在共振頻率附近呈現平坦狀態,以保護馬達免於損壞。
下方圖表顯示 LRA 馬達的 FOAM 範例。
人類感知偵測門檻
「人類感知偵測門檻」是指人類可可靠偵測到的振動最小加速度。這項等級會因震動頻率而異。
下方圖表顯示人類觸覺感知偵測閾值 (以加速度表示),以時間頻率做為函數。閾值資料是根據 Bolanowski Jr. 圖 1 中的位移閾值轉換而來,S. J. 等人於 1988 年發表的文章「Four channels mediate the mechanical aspects of touch」。
Android 會在 BasicEnvelopeBuilder
中自動處理這個門檻,以驗證所有效果使用的頻率範圍,產生的振動振幅至少會超過人類感知偵測門檻 10 dB。
線上教學課程進一步說明加速度振幅和位移振幅之間的轉換。
振動加速度等級
人類對振動強度的感知 (感知測量) 並不會隨著振動幅度 (物理參數) 線性增加。感知強度以感知音量 (SL) 為特徵,其定義為在相同頻率下,高於偵測閾值的 dB 值。
對應的振動加速度振幅 (以 G 峰值為單位) 的計算方式如下:
其中振幅 dB 是特定頻率下 SL 和偵測閾值 (相鄰圖表中沿垂直軸的值) 的總和。
下方圖表顯示 10、20、30、40 和 50 dB SL 的振動加速度等級,以及人類觸覺感知偵測閾值 (0 dB SL),以時間頻率為函式。這項資料是根據 Verrillo, R. T. 等人於 1969 年發表的論文「Sensation magnitude of vibrotactile stimuli」。
Android 會在 BasicEnvelopeBuilder
中自動處理這項轉換作業,將值視為感知音量空間 (dB SL) 中的標準化強度,並轉換為輸出加速度。另一方面,WaveformEnvelopeBuilder
不會套用這項轉換,而是將值視為加速度空間 (Gs) 中的標準化輸出加速度振幅。封套 API 會假設設計人員或開發人員在考慮震動強度變化時,會希望感知強度遵循區域線性封套。
裝置上的預設波形平滑處理
舉例來說,請考慮自訂波形模式在一般裝置上的行為:
Kotlin
val timings: LongArray = longArrayOf(50, 50, 50, 50, 50, 100, 350, 250)
val amplitudes: IntArray = intArrayOf(77, 79, 84, 99, 143, 255, 0, 255)
val repeatIndex = -1 // Don't repeat.
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex))
Java
long[] timings = new long[] { 50, 50, 50, 50, 50, 100, 350, 250 };
int[] amplitudes = new int[] { 77, 79, 84, 99, 143, 255, 0, 255 };
int repeatIndex = -1 // Don't repeat.
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex));
下列圖表顯示輸入波形和輸出加速度,對應前述程式碼片段。請注意,每當模式中的振幅出現階梯式變化 (即 0ms、150ms、200ms、250ms 和 700ms) 時,加速度會逐漸增加,而非突然增加。在每個振幅階梯變化時,也會出現過衝現象,而且當輸入振幅突然降至 0 時,會出現持續至少 50 毫秒的明顯振鈴聲。
改善觸覺回饋模式
為避免過度超出並縮短振鈴時間,請更漸進地變更振幅。以下是修訂版的波形和加速度圖表:
Kotlin
val timings: LongArray = longArrayOf(
25, 25, 50, 25, 25, 25, 25, 25, 25, 25, 75, 25, 25,
300, 25, 25, 150, 25, 25, 25
)
val amplitudes: IntArray = intArrayOf(
38, 77, 79, 84, 92, 99, 121, 143, 180, 217, 255, 170, 85,
0, 85, 170, 255, 170, 85, 0
)
val repeatIndex = -1 // Do not repeat.
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex))
Java
long[] timings = new long[] {
25, 25, 50, 25, 25, 25, 25, 25, 25, 25, 75, 25, 25,
300, 25, 25, 150, 25, 25, 25
};
int[] amplitudes = new int[] {
38, 77, 79, 84, 92, 99, 121, 143, 180, 217, 255, 170, 85,
0, 85, 170, 255, 170, 85, 0
};
int repeatIndex = -1; // Do not repeat.
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex));
建立更複雜的觸覺技術效果
滿意點擊回應中的其他元素則較為複雜,需要瞭解裝置中使用的 LRA。為了獲得最佳結果,請使用裝置預先建構的波形和平台提供的常數,以便執行下列操作:
- 執行清晰效果和基本元素。
- 將這些音效串連起來,組合成新的觸覺效果。
這些預先定義的觸覺常數和基本元素可大幅加快您的工作速度,同時創造高品質的觸覺效果。