实现触感反馈

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

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

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

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

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

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

触感反馈实现核对清单

  1. 实现常量

    • 实现触感反馈所需的常量列表。
  2. 在 HAL 和 API 之间映射常量

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

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

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

第 1 步:实现常量

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

触感反馈实现流程图

图 2. 实现效果

实现基元的步骤流程图

图 3. 实现基元

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

触感反馈常量 位置及摘要
EFFECT_TICKEFFECT_CLICKEFFECT_HEAVY_CLICKEFFECT_DOUBLE_CLICK VibrationEffect
VibrationEffect 中的触感反馈常量不包含任何输入事件的概念,也没有界面元素,而是包含能量等级的概念,例如 EFFECT_CLICKEFFECT_HEAVY_CLICK,这些常量由 createPredefined() 调用。
PRIMITIVE_TICKPRIMITIVE_CLICKPRIMITIVE_LOW_TICK>PRIMITIVE_SLOW_RISEPRIMITIVE_QUICK_RISEPRIMITIVE_QUICK_FALLPRIMITIVE_SPINPRIMITIVE_THUD VibrationEffect.Composition
系统允许 VibrationEffect.Composition 中的触感反馈常量带有可调节的强度,这些常量由 addPrimitive(int primitiveId, float scale, int delay) 调用。

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

  1. EFFECT_CLICK

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

  2. EFFECT_HEAVY_CLICK

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

  3. EFFECT_DOUBLE_CLICK

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

  4. 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 步:在 HAL 和 API 之间映射常量

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

  • 离散模型(简单)

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

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

离散模型

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

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

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

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

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

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

图 6. 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),如图 7 所示。通过使用连续模型的振幅调节功能,设备可以存储具有独特纹理的少量 HAL 常量,并通过调整调节系数 (S) 来添加振幅变体。设备制造商可以根据自己想要提供的不同触感反馈纹理的数量来指定 HAL 常量的数量。

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

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

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

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

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

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

增加变体 1

增加变体 2

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

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

第 3 步:评估硬件

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

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

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

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

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

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

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

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

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

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

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

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

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

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

执行主观评估

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

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