Android 触感 API 参考

本部分介绍了 Android 中提供的各种触感 API。同时涵盖了何时以及如何检查设备支持情况,以确保您的触感效果按预期播放。

创建触感效果有多种不同的方法,在选择时,必须考虑 Android 触感 设计原则。下表总结了每种方法的高级属性。

  • 在规划行为回退(fallback)时,可用性尤为重要,需要结合对单个设备的支持情况进行检查。
  • 清晰触感 (Clear haptics) 是干脆利落的触觉反馈,对用户而言干扰较小。
  • 丰富触感 (Rich haptics) 具有更强的表现力,通常需要功能更强大的硬件支持。
API 表面 可用性 清晰触感 丰富触感
HapticFeedbackConstants Android 1.5+
(按常量计算)
预定义的 VibrationEffect Android 10+
VibrationEffect 组合 Android 11+(按常量计算)
开关、单次触发和波形振动 Android 1

此外,本页所述的 通知 API 允许您自定义播放传入通知时的触感效果。

本页还介绍了跨 API 表面的其他概念。

HapticFeedbackConstants

HapticFeedbackConstants 类提供了基于操作的常量,允许应用添加在整个设备体验中保持一致的触觉反馈,而不是让每个应用对常见操作使用不同的效果。

兼容性和要求

使用带有这些常量的 View.performHapticFeedback 方法不需要任何特殊权限。它受 View.hapticFeedbackEnabled 属性的约束,如果设置为 false,将禁用视图上的所有触觉反馈调用,包括默认调用。此外,该方法还遵循用户关于启用触摸反馈的系统设置。

唯一的兼容性考量因素是特定操作常量的 SDK 级别。

使用 HapticFeedbackConstants 时无需提供回退行为。

HapticsFeedbackConstants 的使用

有关使用 HapticFeedbackConstants 的详细信息,请参阅 为事件添加触觉反馈

预定义的 VibrationEffect

VibrationEffect 类提供了多种预定义常量,例如 CLICKTICKDOUBLE_CLICK。这些效果可能已针对设备进行了优化。

兼容性和要求

播放任何 VibrationEffect 都需要在应用清单中声明 VIBRATE 权限。

使用预定义的 VibrationEffect 时无需提供回退行为,因为没有设备优化实现效果的常量会退回到标准平台回退。

Vibrator.areEffectsSupportedVibrator.areAllEffectsSupported API 用于确定是否存在设备优化实现。预定义效果即使没有优化实现也可以使用,并会使用标准平台回退。因此,仅当应用程序想要考虑效果是否针对设备进行了优化时,才需要使用这些 areEffectsSupported API。

效果检查方法可返回以下三个值之一:

由于 UNKNOWN 值表示检查 API 不可用,因此它通常对所有效果或所有效果都不返回。这些设备会动态进行回退。

预定义 VibrationEffect 的使用

有关使用预定义 VibrationEffect 的详细信息,请参阅 使用预定义的 VibrationEffect 生成触觉反馈

包络振动效果 (Envelope VibrationEffect)

基于包络的振动通过定义一系列控制点,允许在时间上精确控制振动的振幅和频率。这使得开发人员能够制作更丰富、更细腻的触觉反馈体验。这些振动可以使用 BasicEnvelopeBuilderWaveformEnvelopeBuilder 类创建。

兼容性和要求

要播放任何振动效果,您的应用必须在应用清单中声明 VIBRATE 权限。

要检查是否支持包络效果,请调用 Vibrator.areEnvelopeEffectsSupported()

基础包络构建器 (Basic Envelope Builder)

为了创造流畅无缝的触感体验,包络效果必须以强度 \( 0.0 \) 开始并结束。API 通过将起始强度固定为零来强制执行此操作,如果结束强度不为零,则会抛出异常。这种约束防止了因振幅不连续而导致的振动中出现不理想的动态效果,从而避免对用户的触觉感知产生负面影响。

为了在不同设备上提供一致的包络效果渲染,框架要求支持此功能的设备能够处理控制点之间至少 20 毫秒的持续时间,并且至少支持 16 个包络效果控制点。

波形包络构建器 (Waveform Envelope Builder)

框架不会修改开发人员请求的频率和振幅值。但是,为了创建平滑的过渡,API 会将起始振幅固定为零。

为了帮助您优化应用的波形包络效果并提供跨设备兼容性,Android 提供了查询重要设备功能的 API。这些方法提供有关设备限制的信息,例如控制点之间的最大和最小过渡持续时间,以及单个效果支持的最大控制点数。

getMaxSize()
检索包络效果支持的最大控制点数。
getMinControlPointDurationMillis()
检索包络效果中两个控制点之间支持的最小持续时间(以毫秒为单位)。
getMaxControlPointDurationMillis()
检索包络效果中两个控制点之间支持的最大持续时间(以毫秒为单位)。
getMaxDurationMillis()
检索包络效果支持的最大持续时间(以毫秒为单位)。

如果效果超过了设备的限制(例如控制点过多或持续时间超过最大值),框架会自动调整效果以使其符合允许的边界。此调整过程会尽可能保留原始设计意图和手感。

包络 VibrationEffects 的使用

有关创建包络波形效果的详细信息,请参阅 创建带包络的振动波形

VibrationEffect 组合

VibrationEffect 组合是一种使用 VibrationEffect.startComposition API 创建的振动效果。此 API 通过创建具有自定义延迟和强度的基元序列,实现了富有表现力的 丰富触感。但是,请务必确保设备支持所组合的功能,以避免导致整体体验不一致。

兼容性和要求

播放任何 VibrationEffect 都需要在应用清单中声明 VIBRATE 权限。

并非所有设备都支持组合 API 的所有功能,确保基元 (primitives) 可用非常重要。

检查振动基元支持

可以使用 Vibrator.arePrimitivesSupported 方法检索单个基元的支持情况。或者,也可以通过使用 Vibrator.areAllPrimitivesSupported 方法一起检查一组基元——这等同于对每个基元的支持情况进行 AND 运算。

VibrationEffect 组合的使用

有关使用 VibrationEffect 组合的详细信息,请参阅 创建振动组合

开关、单次触发和波形振动

Android 上支持的最古老的振动形式是具有可配置持续时间的简单振动器开关模式。这些 API 通常与 触感设计原则 不太一致,因为它们会产生 嗡嗡触感;除非万不得已,否则请避免使用它们。

开关振动最常见的用例是通知,无论如何,用户都需要某种振动。波形振动还允许模式无限重复,正如您想象中的铃声一样。

单次触发模式是指振动一次,持续 N 毫秒。

有两种类型的波形模式:

  • 仅限时序。 这种类型的波形是对交替持续时间(关闭时长和开启时长)的描述。时序从关闭的持续时间开始。因此,波形模式通常以零值开始,以指示立即开始振动。
  • 时序和振幅。 这种类型的波形有一个额外的振幅数组,以匹配每个时序数据,而不是第一种形式的隐含开关。但是,请务必检查设备是否支持振幅控制,以确保实现预期的缩放效果。

兼容性和要求

由于开关振动是最古老的振动形式,因此几乎所有 带有振动器 的设备都支持它(如下文所述)。

播放任何 VibrationEffect 或旧式的 vibrate 调用都需要在应用清单中声明 VIBRATE 权限。

在波形中使用不同的振幅值时,我们强烈建议您确认设备是否支持振幅控制

检查振幅控制支持

在不支持振幅控制的设备上,非零振幅值会被向上取整到 100%,因此使用 Vibrator.hasAmplitudeControl 检查是否存在该支持非常重要。有关更多详细信息,请参阅 振幅控制

您应该仔细考虑在没有振幅控制的情况下,您的效果质量是否足够。回退到专门设计的开关振动方案可能更好。

开关振动的使用

在较新的 SDK 级别中,所有振动模式都整合到了一个表现力丰富的 VibrationEffect 类中,其中这些简单的振动使用 VibrationEffect.createOneshotVibrationEffect.createWaveform 创建。

通知 API

自定义应用通知时,可以使用以下 API 之一将模式与每个通知渠道关联:

所有这些形式都采用如前所述的基本 开关波形模式,其中第一项是开启振动器前的延迟。

通用概念

多个概念适用于上述所有 API 表面。

设备是否有振动器?

您可以从 context.getSystemService(Vibrator.class) 获取非空的 Vibrator 类。如果设备没有振动器,调用振动 API 不会有任何效果,因此应用无需在条件中对其所有触感进行控制。但是,如有必要,应用程序可以调用 hasVibrator() 来确定这是一个真实的振动器(true)还是一个存根(false)。

用户是否禁用了触摸触感?

某些自定义实现可能需要手动检查用户是否完全禁用了 Android 的 触摸反馈 设置,在这种情况下应抑制触摸反馈效果。可以使用 HAPTIC_FEEDBACK_ENABLED 键查询此设置,其中值为零表示已禁用。

振动属性

可以提供振动属性(目前以 AudioAttributes 的形式)来帮助告知系统振动的目的。当您的应用在后台运行时启动振动时,这是必需的,因为后台仅支持注意力触感。

AudioAttributes 的创建在其类文档中有介绍,应将其视为振动而非声音

作为参考,在大多数情况下,内容类型为 CONTENT_TYPE_SONIFICATION,用途可能是 USAGE_ASSISTANCE_SONIFICATION(用于前台触摸反馈)或 USAGE_ALARM(用于后台闹钟)等值。音频标志对振动没有影响。

振幅控制

如果振动器具有振幅控制功能,则可以播放具有不同强度的振动。这是产生 丰富触感 的一项重要功能,也可能允许用户控制默认的触感强度。

可以通过调用 Vibrator.hasAmplitudeControl 来检查振幅控制支持。如果振动器不支持振幅,所有振幅值将根据它们是零还是非零映射到关/开状态。因此,如果设备缺乏振幅控制,使用不同振幅的丰富触感应用应考虑禁用它们。

包络效果支持

具有包络效果支持的振动器能够创建更具动态和细腻的振动,为更丰富的触感体验提供更精确的强度和锐度控制。使用 Vibration.areEnvelopeEffectsSupported 来确定您的设备是否支持此功能。如果不支持,基于包络的振动将被忽略。