触感框架的 UX 基础

围绕触感反馈构建的所有 Android 框架改进均由一组 UX 原则驱动,这些原则也在以相同的速度发展。当前的原则包括将嗡嗡振动替换为清晰触感,并探索丰富触感

UX Principles

图 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基于蜂鸣器的振动一直被用作静音模式下听觉铃声的替代品。产生响亮且令人不悦的音频噪声的旧式硬件组件可能会通过传递低质量的印象(例如,便宜的、坏掉的手机)来损害触感反馈 UX。

清晰触感

清晰触感支持离散状态变化的感觉(例如,电源开启/关闭过程中的二进制变化)。由于离散示能的性质,清晰触感是作为一个实体生成的(例如,每个输入事件一个触感效果)。

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,详细了解触感反馈实现。

Press and Release

图 3. 按下和释放。

丰富触感

丰富触感是一个不断发展的触感反馈类别,它超越了基于单脉冲的效果。Android 旨在支持具有高可组合性和可调节性以及精细粒度的丰富触感。Android 11 或更低版本支持以下用例。

Rich Haptics

图 4. 具有滑动纹理的丰富触感

Dragging and Swiping

图 5. 拖动和滑动

用例 1:滑动纹理

如果在手指在触摸表面上滑动时重复触感效果(例如,拖动、滑动、使用幻象触感纹理探索表面),则重复的触感效果最好是清晰而微妙的。

如果单个效果是嗡嗡作响而不是清晰的,那么重复之间的间隔很可能会被消除。结果是一个长嗡嗡声,而不是多个离散信号。

如果振幅不够微妙,那么感知的触感反馈能量会通过重复累积,从而在重复结束时产生非常强烈的触感反馈。

为滑动和拖动手势实现简单的表面触感纹理

HapticFeedbackConstants 中使用 CLOCK_TICKTEXT_HANDLE_MOVE。这些常量预定义了重复和振幅的特征。

创建您自己的效果

要创建您自己的效果,请通过将 VibrationEffect.Composition 中的 PRIMITIVE_CLICKPRIMITIVE_TICK 序列串联在一起来组合设计。您可以使用 addPrimitive(int primitiveID, float scale, int delay) 调整重复和振幅比例的特征。支持依赖于 CAP_COMPOSE_EFFECTS Vibrator HAL 接口的功能。

用例 2:具有缓入效果的长振动

长振动是一种平滑的振幅振动,它从 0 过渡到目标振幅。长振动可以产生容易感知的注意力触感反馈。然而,突然的长振动可能会在安静的环境中惊吓用户,并且经常产生可听见的嗡嗡噪声。为了产生更令人愉悦的长振动,请在长振动开始时应用缓入效果。这将产生一个平滑的振幅过渡,逐渐建立到目标振幅。

应用缓入效果

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

    • 结果必须为 true 才能产生具有可变振幅的缓入效果。
  2. 使用 VibrationEffectcreateWaveform(timings[], amplitudes[], int repeat)

  3. 调整 timings[]amplitudes[] 系列以生成缓入曲线,如图 6 所示。

Long Vibration

图 6. 长振动缓入曲线

用例 3:音频耦合触感反馈

音频耦合触感反馈是与音频节奏耦合的触感反馈模式,用于引起用户的注意。

音频耦合触感反馈:优势

要实现音频耦合触感反馈,请将清晰触感与长振动相结合。来自清晰触感的强烈但短暂的触感感觉传递离散的节奏模式。当与长振动提供的高水平刺激相结合时,这在引起用户注意方面做得非常出色。

重要的是要考虑感觉节奏模式。如果没有节奏感,用户会将触感反馈感觉视为随机的嗡嗡声,并且倾向于忽略它们。

Audio Couple

图 7. 音频耦合触感反馈示例

音频耦合触感反馈:实现技巧

实现音频耦合触感反馈需要基本了解音频和触感反馈通道的内容播放。请记住以下几点。

  • 使用 MediaPlayerSoundPool 类。

    • 具有特殊元数据键(ANDROID_HAPTIC 后跟触感反馈通道号)的 OGG 格式资源表示存在触感反馈数据,并使用 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 必须实现外部控制支持。

Audio Coupled Haptics

图 8. 实现音频耦合触感反馈

音频耦合触感反馈:触感反馈生成器

HapticGenerator 是 Android 12 中引入的音频效果,它可以从音频通道生成触感反馈数据,并以实时方式作为音频耦合触感反馈播放。该效果应用于 AudioTrack,如图 9 所示。

Haptic Generator architecture

图 9. 触感反馈生成器架构

为确保您的触感反馈生成器算法生成高质量的触感反馈,请通过调整配置应用于音频波形的滤波器链的参数,将生成算法调整到设备振动器电机。本节详细介绍了这些参数,并解释了如何根据您的硬件规格调整这些参数。

  1. 带通滤波器的谐振频率

    振动器谐振频率是触感反馈致动器具有最大输出的频率。此参数调整抗谐振器以部分展平响应传递函数,以便获得更宽的带宽。Android 框架自动将此值链接到 Vibrator HAL 方法 IVibrator.getResonantFrequency 的输出。

    此参数的默认值为 150Hz。可以在此处的代码中修改此值。

  2. 慢速包络线的归一化功率

    此参数确定部分归一化(自动增益控制)中的指数。其默认值为 -0.8,这意味着动态范围变化的 80% 通过此增益控制步骤消除。可以在此处的代码中修改此值。

  3. 带阻滤波器的 Q 因子

    振动器品质因数(Q 因子)由两个参数确定

    • 零 Q,带阻滤波器中零点的品质因数,它部分抵消谐振。

    • 极点 Q,带阻滤波器中极点的品质因数。

    这两个值的比率限制了谐振的抑制,以便增强较低频率并拓宽算法响应。例如,零 Q 的默认值 8 和极点 Q 的默认值 4 产生的比率为 2,将谐振抑制限制为 2 倍(6 dB)。Android 框架将这两个值都链接到 Vibrator HAL 方法 IVibrator.getQFactor 的输出。

    如果默认值未考虑设备中电机强度的衰减,我们建议同时修改这两个值,并同时增加或同时减小这两个值。零 Q 与极点 Q 的比率应大于 1。可以在此处的代码中修改此值。

  4. 失真转角频率

    转角频率由低通滤波器应用,该滤波器抑制低电平振动并使用三次失真增强更高电平。它默认为 300Hz。可以在此处的代码中修改此值。

  5. 失真的输入增益和立方体阈值

    这些参数由应用于输入波形的非线性失真滤波器使用,该滤波器衰减较低频率信号的振幅并增加较高频率信号的振幅。

    • 输入增益因子的默认值为 0.3
    • 立方体阈值的默认值为 0.1

    我们建议一起修改这两个值。它们可以在此处的代码中找到。

    有关此滤波器应用的函数的更多信息,请参阅此处提供的实现。要详细了解这两个参数如何影响输出,我们建议绘制滤波器的频率响应,并观察频率响应如何随不同的参数值而变化。

  6. 失真的输出增益

    此参数控制最终振动幅度。它是在软限制器之后应用的最终增益,该限制器将振动幅度限制为小于 1。其默认值为 1.5,可以在此处的代码中修改此值。如果振动过于细微,请增加该值。如果您可以听到致动器硬件嘎嘎作响,请减小该值。