实现触感反馈

设备制造商通常被认为是为每个设备创建的私有资产的所有者。因此,他们的工程工作往往围绕每台设备集中展开;为确保与生态系统中其他设备的一致性而开展的工作很少,甚至完全没有。

与之形成鲜明对比的是,开发者在努力构建可在生态系统中的所有 Android 手机上运行的应用(无论每类设备的技术规范如何)。这种方法上的差异可能会导致碎片化问题,例如,某些手机的硬件功能不符合应用开发者设定的预期。因此,如果触感反馈 API 适用于某些 Android 手机,但不适用于其他 Android 手机,就会导致生态系统不一致。正因如此,硬件配置在确保制造商能够在每台设备上实现 Android 触感反馈 API 方面发挥着关键作用。

本页面提供了一个分步核对清单,用于确保硬件合规,从而使得 Android 触感反馈 API 能充分发挥作用。

下图说明了如何在设备制造商和开发者之间建立共识,这是打造具有凝聚力的生态系统的关键一环:

应用开发者和设备制造商的触感反馈用例示意图

图 1. 在设备制造商和开发者之间建立共识

触感反馈实现核对清单

  1. 实现常量

    • 实现触感反馈所需的常量列表。
  2. 实现基元

    • HAL 组合基元的实现指南。
  3. 在 HAL 和 API 之间映射常量

    • 公共 API 常量(在框架中名为占位符)和 HAL 常量(用于实现占位符)之间的映射建议。
    • 如需详细了解此流程,请参阅指导推荐映射的设计原则
  4. 评估硬件

    • 有关目标触感反馈效果的说明。请按照相关说明对硬件执行快速检查。

我们将在下文中更详细地介绍每个步骤。

第 1 步:实现常量

执行以下检查,确定您的设备是否满足实现触感反馈的最低要求:

触感反馈实现流程图

图 2. 实现效果

实现基元的步骤流程图

图 3. 实现基元

检查以下触感反馈常量的实现状态。

触感反馈常量 位置及摘要
EFFECT_TICKEFFECT_CLICKEFFECT_HEAVY_CLICKEFFECT_DOUBLE_CLICK VibrationEffect
VibrationEffect 中的触感反馈常量不包含任何输入事件的概念,也没有界面元素,而是包含能量等级的概念,例如 EFFECT_CLICKEFFECT_HEAVY_CLICK,这些常量由 createPredefined() 调用。

下面所述的备用振动在未实现 VibrationEffect 常量的设备上执行。建议更新这些配置,以在此类设备上获得最佳性能。

  • EFFECT_CLICK

    使用 VibrationEffect.createWaveform 创建的波形振动,以及在 frameworks/base/core/res/res/values/config.xml##config_virtualKeyVibePattern 配置的时间。

  • EFFECT_HEAVY_CLICK

    使用 VibrationEffect.createWaveform 创建的波形振动,以及在 frameworks/base/core/res/res/values/config.xml##config_longPressVibePattern 配置的时间。

    • EFFECT_DOUBLE_CLICK

    使用 VibrationEffect.createWaveform 创建的波形振动,以及时间 (0, 30, 100, 30)。

  • EFFECT_TICK

    使用 VibrationEffect.createWaveform 创建的波形振动,以及在 frameworks/base/core/res/res/values/config.xml##config_clockTickVibePattern 配置的时间。

测试触感反馈的步骤流程图

图 4. 实现反馈常量

检查以下公开反馈常量的状态。

触感反馈常量 位置及摘要
CLOCK_TICKCONTEXT_CLICKKEYBOARD_PRESSKEYBOARD_RELEASEKEYBOARD_TAPLONG_PRESSTEXT_HANDLE_MOVEVIRTUAL_KEYVIRTUAL_KEY_RELEASECONFIRMREJECTGESTURE_STARTGESTURE_END HapticFeedbackConstants
HapticFeedbackConstants 中的触感反馈常量可协助处理某些界面元素的输入事件,例如 KEYBOARD_PRESSKEYBOARD_RELEASE,这些事件由 performHapticFeedback() 调用。

第 2 步:实现基元

VibrationEffect.Composition 中的触感反馈基元带有可调节的强度,开发者可以通过 addPrimitive(int primitiveId, float scale, int delay) 加以使用。这些基元可分为两类:

  • 短基元:持续时间较短(通常不到 20 毫秒)的基元。这类基元包括 CLICKTICKLOW_TICK

  • 线性调频基元:振幅和频率会发生变化的基元,通常持续时间比短基元长。这类基元包括 SLOW_RISEQUICK_RISEQUCK_FALLTHUDSPIN

短基元

短基元可以通过振动器电机输出加速度配置文件进行描述。每个基元使用的绝对频率各不相同,具体取决于致动器的共振频率。如需详细了解硬件设置和用于测量输出的工具,请参阅设置测试设备

脉冲到响铃比率 (PRR) 是短时间振动的一个有价值的质量指标,如图 5 所示。PRR 定义为主脉冲响铃脉冲的比率。主脉冲由振幅下降到峰值振幅的 10% 这段时间内的信号定义,而响铃脉冲由振幅从峰值振幅的 10% 下降到低于峰值振幅的 1% 这段时间内的信号定义。有关 PRR 的更多信息,请参阅分析波形。如需详细了解如何分析和比较结果,请参阅使用性能图比较结果

脉冲到响铃比率

图 5. 脉冲到响铃比率的定义

短基元可以用作用户输入反馈,或者在较长的组合中播放,以创建柔和的纹理。这意味着它们通常会频繁触发并快速连续播放。单个短基元的感知强度可能会加剧更大的效果强度。所以在校准单个 Tick 或 Low Tick 基元时,请使用更大的组合(例如 100 个连续的 Tick)。

Click 基元

Click 基元是一种强烈、利落的效果,通常在接近设备共振频率的情况下运行,用于在短时间内达到最大输出。它比其他基元更强烈、更深刻,并且以最大强度执行。

如果可以,请在开始时使用电机过载,并在结束时使用主动制动,以实现较短的电机上升和下降时间。对于某些电机,使用方波(而非正弦波)可以实现更快的加速。图 6 显示了 Click 基元的输出加速度配置文件的示例:

Click 基元的输出加速度配置文件

图 6. 示例:Click 基元的输出加速度配置文件

参数 指导原则
持续时间

目标:12 毫秒

限制:< 30 毫秒

峰值输出加速度

目标:2 G

限制:> 1 G

频率 大致等于共振频率

Tick 基元 (Light Tick)

Tick 基元是一种急速剧烈的短效应,通常在较高的频率范围内运行。此基元也可描述为中等强度、较高频率的 Click,尾部较短。此基元也适用相同的指导原则,即在最初触发时使用电机过载或方波,并在结束时使用主动制动,以实现较短的电机上升和下降时间。图 7 显示了 Tick 基元的输出加速度配置文件的示例:

Tick 基元的输出加速度配置文件

图 7. 示例:Tick 基元的输出加速度配置文件

参数 指导原则
持续时间

目标:5 毫秒

限制:< 20 毫秒

峰值输出加速度

目标:CLICK 的一半,1 G

限制:介于 0.5 G 到 1 G 之间

频率

目标:2x 共振频率

限制:< 500 Hz

Low Tick 基元

Low Tick 基元是更轻、更柔和的 Light Tick,在较低的频率范围内运行,可以为效果提供更多请求体。此基元也可描述为中等强度、较低频率的 Click,旨在重复用于动态反馈。此基元也适用相同的指导原则,即在最初触发时使用电机过载或方波,以实现较短的电机上升时间。图 8 显示了 Low Tick 基元的输出加速度配置文件的示例:

Low Tick 基元的输出加速度配置文件

图 8. 示例:Low Tick 基元的输出加速度配置文件

参数 指导原则
持续时间

目标:12 毫秒

限制:< 30 毫秒

峰值输出加速度

目标:TICK 的四分之一,0.25 G

限制:介于 0.2 G 到 0.5 G 之间

频率

目标:2/3 共振频率

限制:< 100 Hz

线性调频基元

线性调频基元可以通过电压水平和振动频率的输入信号进行描述。电机在不同频率范围内能够输出的加速度因致动器的频率响应曲线而异。频率范围和电压水平需要针对每台设备进行调整。

Slow Rise 基元

Slow Rise 是指缓慢的向上振幅和频率扫描,以柔和的方式开始,在扫描过程中振动强度持续增加。此基元可通过振幅和频率始终一致的扫描来实现(使用不产生共振的较低频率范围)。图 9 显示了此实现的输入参数和输出加速度配置文件的示例。(红线与左侧的振幅标签相对应,表示振幅随时间的变化情况。蓝线与右侧的频率标签相对应,表示振动频率随时间的变化情况。)

Slow Rise 基元的输入参数和输出加速度配置文件

图 9. 示例:Slow Rise 基元的输入参数和输出加速度配置文件

如果电机的频率响应有限(在其共振频率之外响应不够强),则可以改为使用介于 1/2 到 1x 共振频率之间的正弦扫描来实现。电机共振有助于在结束时达到信号峰值。

参数 指导原则
持续时间

目标:500 毫秒

容差:20 毫秒

峰值输出加速度

目标:0.5 G

限制:介于 0.5 G 到 1 G 之间

频率

目标:1/2 至 2/3 共振频率

替代方案:1/2 至 1x 共振频率

Quick Rise 基元

Quick Rise 是指速度更快的向上振幅和频率扫描,开始时较为柔和,而且在扫描过程中,振动强度会持续增加。输出加速度和振动频率的目标值应与 Slow Rise 基元相同,但实现这些值的持续时间更短。图 10 显示了 Quick Rise 基元的振动输入参数和输出加速度配置文件的示例。(红线与左侧的振幅标签相对应,表示振幅随时间的变化情况。蓝线与右侧的频率标签相对应,表示振动频率随时间的变化情况。)

Quick Rise 基元的输入参数和输出加速度配置文件

图 10. 示例:Quick Rise 基元的输入参数和输出加速度配置文件

参数 指导原则
持续时间

目标:150 毫秒

容差:20 毫秒

峰值输出加速度

目标:与 SLOW_RISE 相同

限制:与 SLOW_RISE 相同

频率

目标:与 SLOW_RISE 相同

替代方案:与 SLOW_RISE 相同

Quick Fall 基元

Quick Fall 是指快速的向下振幅和频率扫描,开始时较为柔和。在开始时,您可以使用较高的频率,并让电机迅速加速至峰值输出加速度。频率应在扫描过程中持续降低(即使是在电机上升期间)。图 11 显示了此实现的输入参数和输出加速度配置文件的示例。(红线与左侧的振幅标签相对应,表示振幅随时间的变化情况。蓝线与右侧的频率标签相对应,表示振动频率随时间的变化情况。)

Quick Fall 基元的输入参数和输出加速度配置文件

图 11. 示例:Quick Fall 基元的输入参数和输出加速度配置文件

参数 指导原则
持续时间

目标:100 毫秒

容差:20 毫秒

峰值输出加速度

目标:1 G

限制:介于 0.5 G 到 2 G 之间

频率

目标:2x 至 1x 共振频率

Thud 基元

Thud 是一种低沉的敲击效果,可模拟敲击空心木材的物理感觉。此基元在低频范围内运行,类似于 Low Tick 基元,可以为效果提供更多请求体。您可以将 Thud 基元实现在较低频率范围(最好低于 100 Hz)内进行的向下振幅和频率扫描。图 12 显示了此实现的输入参数和输出加速度配置文件的示例。(红线与左侧的振幅标签相对应,表示振幅随时间的变化情况。蓝线与右侧的频率标签相对应,表示振动频率随时间的变化情况。)

Thud 基元的输入参数和输出加速度配置文件

图 12. 示例:Thud 基元的输入参数和输出加速度配置文件

如果电机的频率响应有限,可考虑在开始时以共振频率发出全强度驱动信号,再降低至可感知的最低频率。此方法可能需要提高低频驱动信号强度,以便感受到振动。

参数 指导原则
持续时间

目标:300 毫秒

容差:20 毫秒

峰值输出加速度

目标:0.25 G

限制:介于 0.2 G 到 0.5 G 之间

频率

目标:1/2 至 1/3 共振频率

替代方案:1x 至 1/2 共振频率

Spin 基元

Spin 用于模拟快速上下旋转的旋转动量,并在中心位置添加了轻微的强调符号。Spin 可以通过独立地在相反方向扫描振幅和频率,再进行反向运动来实现。请务必使用较低的频率范围(最好低于 100 Hz)。图 13 显示了此实现的输入参数和输出加速度配置文件的示例。(红线与左侧的振幅标签相对应,表示振幅随时间的变化情况。蓝线与右侧的频率标签相对应,表示振动频率随时间的变化情况。)

我们建议连续调用 Spin 基元两次(或在组合中调用三次),以实现旋转和不稳定的感觉。

如果电机的频率响应有限,则可以改为使用介于 1/2 到 1x 共振频率之间的快速正弦扫描来实现。电机共振会自动在信号正中添加强调符号。

Spin 基元的输入参数和输出加速度配置文件

图 13. 示例:Spin 基元的输入参数和输出加速度配置文件

参数 指导原则
持续时间

目标:150 毫秒

容差:20 毫秒

峰值输出加速度

目标:0.5 G

限制:介于 0.25 G 到 0.75 G 之间

频率

目标:2/3 至 1/3 共振频率,然后回到 1/2 共振频率

替代方案:2/3 至 1x 共振频率,然后回到 1/2 共振频率

第 3 步:在 HAL 和 API 之间映射常量

第 3 步展示了公共 HAL 常量和 API 常量之间的推荐映射。如果第 1 步中评估的硬件未实现 HAL 常量,请使用第 3 步来更新第 1 步中所述的回退模式,以生成类似输出。映射由两个不同的默认模型辅助完成:

  • 离散模型(简单)

    • 振幅是此模型的关键变量。HAL 中的每个实体都代表一个不同的触感反馈振幅。
    • 此模型是实现基本触感反馈用户体验的最低要求。
    • 如需实现更高级的触感反馈用户体验,需要使用高级硬件和高级模型(连续模型)。
  • 连续模型(高级)

    • 纹理和振幅是此模型的关键变量。HAL 中的每个实体都代表不同的触感反馈纹理。每个 HAL 实体的振幅都由调节系数 (S) 控制。
    • 此模型需要高级硬件。如果原始设备制造商 (OEM) 想要通过 VibrationEffect.Composition(以充分利用最新的触感反馈 API)实现高级触感反馈用户体验,建议使用此模型实现其硬件。

离散模型

建议将该 API 中提供的所有公共常量与相应的 HAL 常量进行映射。如需开始此过程,请了解设备可以在 HAL 中指定多少个具有离散振幅的触感反馈波形。围绕该概念产生的具体问题类似于:我的手机中可以指定多少个具有人类可感知的振幅差异的单脉冲触感反馈效果?此问题的答案决定了需要执行的映射。

指定 HAL 常量的过程依赖于硬件。例如,入门级手机的硬件功能可能只能产生单个触感反馈波形。配备更高级硬件组件的设备可以产生更广泛的离散振幅级别,并在 HAL 中指定多个触感反馈波形。在进行 HAL-API 常量映射时,需要先选取 HAL 常量(使用中等振幅作为基准),然后以此为基础安排更强或更弱的效果。

HAL 常量范围和反馈振幅示意图

图 14. HAL 常量范围(按振幅)

指定具有离散振幅的 HAL 常量的数量之后,就该按 HAL 常量的数量映射 HAL 和 API 常量了。此映射过程最多可将一个单脉冲 API 常量细分为三组离散的振幅级别。API 常量的细分方式以伴随的输入事件的用户体验原则为基础。如需了解详情,请参阅触感反馈用户体验设计

用于 HAL-API 常量映射的离散模型

图 15. HAL-API 常量映射:离散模型

如果您的设备仅支持两个具有离散振幅的 HAL 常量,请考虑合并“中”和“高”振幅级别的 HAL 常量。在实践中,此概念的一个示例为:将 EFFECT_CLICKEFFECT_HEAVY_CLICK 映射到同一 HAL 常量,这会是“中”振幅级别 HAL 常量。如果您的设备仅支持一个具有离散振幅的 HAL 常量,请考虑将所有三个级别合并为一个。

连续模型

可以通过应用具有振幅调节功能的连续模型来指定 HAL 常数。可将调节系数 (S) 应用于 HAL 常量(例如,HAL_H0HAL_H1),以便生成经过调节的 HAL 常量 (HAL_H0 x S)。在本示例中,经过调节的 HAL 会进行映射,以指定 API 常量 (HAL_H0 x S1 = H0S1 = EFFECT_TICK),如图 16 所示。通过使用连续模型的振幅调节功能,设备可以存储具有独特纹理的少量 HAL 常量,并通过调整调节系数 (S) 来添加振幅变体。设备制造商可以根据自己想要提供的不同触感反馈纹理的数量来指定 HAL 常量的数量。

HAL 常量范围(按纹理和振幅)

图 16. HAL 常量范围(按纹理 [HAL_H0] 和振幅比例 [S])

HAL-API 常量映射的连续模型

图 17. HAL-API 常量映射:连续模型

在连续模型中,不同的 HAL 常量表示不同的触感反馈纹理,而不是不同的振幅;调节系数 (S) 可以配置振幅。但是,由于对纹理的感知(例如,清晰度)与对持续时间和振幅的感知有关,因此建议在 HAL-API 映射的设计过程中将纹理和调节系数结合使用。

图 18 展示了利用振幅调节功能,通过增加变体将一个 HAL 常量映射到多个 API 常量的过程。

增加变体 1

增加变体 2

图 18. 利用振幅调节功能增加变体

对于所有可调节的 API 常量(例如 VibrationEffect.Composition 中的 PRIMITIVE_TICKPRIMITIVE_CLICK),其能量等级取决于通过 addPrimitive(int primitiveID, float scale, int delay) 声明该常量时的 float scale 参数。通过使用不同的 HAL 常量,可以在设计 PRIMITIVE_TICKPRIMITIVE_CLICK 时做出明确的区分。如果要添加纹理变体,建议使用此方法。

第 4 步:评估硬件

进行硬件评估时,需要针对具体评估定义三种触感反馈效果,分别标为效果 1、2 和 3。

效果 1:预定义的短时触感反馈常量

VibrationEffect.EFFECT_CLICK 常量是第 2 步中提供的 HAL-API 映射内的基准效果(即共同标准)。该常量与最常用的效果 HapticFeedbackConstants.KEYBOARD_PRESS 进行映射。评估此效果有助于确定目标设备是否已准备好提供清晰触感反馈

效果 2:短时自定义触感反馈效果

VibrationEffect.createOneShot(20,255) 常量适用于自定义触感反馈效果。对于单次短时自定义脉冲,在指定持续时间时,建议的最大阈值是 20ms。不建议单次脉冲的持续时间超过 20 毫秒,因为这样的脉冲会被视为蜂鸣振动

短时自定义触感反馈效果的波形

图 19. 短时自定义触感反馈效果

效果 3:具有振幅变体的长时自定义触感反馈效果

VibrationEffect.createWaveform(timings[], amplitudes[], int repeat) 常量适用于具有振幅变体的长时自定义触感反馈效果。能否为自定义触感反馈效果生成不同的振幅是评估设备是否有能力提供丰富触感反馈的指标之一。推荐的 timings []amplitudes [] 分别是 {500, 500}{128, 255},表示振幅会从 50% 增加到 100%,并且采样周期为 500 毫秒。

具有振幅变化的触感反馈效果的波形

图 20. 具有振幅变体的长时自定义触感反馈效果

如需检查效果 3 的振幅控制硬件功能,请使用 Vibrator.hasAmplitudeControl() 方法。结果必须为 true,才能按照预期使用不同振幅执行 VibrationEffect.createWaveform

触感反馈效果主观评估流程图

图 21. 对触感反馈效果 1、2 和 3 的主观评估

执行主观评估

若要快速完成一致性检查,请先执行主观评估。主观评估的目标是观察触感反馈效果的振幅,以确定设备能否生成具有人类可感知振幅的触感反馈。

围绕此概念产生的具体问题类似于:设备能否按预期为用户生成可感知的触感反馈效果? 回答此问题有助于您避免失败的触感反馈,包括无法感知的触感反馈(用户感受不到)或意外的触感反馈(波形不产生预期的模式)。

执行高级评估

强烈建议执行高级质量评估。高级质量评估可表征处理触感反馈效果的可量化属性,以便实现高质量触感反馈。完成后,设备制造商就应该能够诊断当前的触感反馈状态,这意味着他们可以设定目标以提高整体质量。请参阅硬件评估