本文档介绍了 Android 中提供的各种触感 API,说明了如何创建不同的触感效果以及如何检查必要的设备支持。 keywords_public: > Android、触感、API、振动、HapticFeedbackConstants、VibrationEffect、 包络触感、触感反馈、通知、振幅控制
本部分简要介绍了 Android 中提供的各种触感反馈 API。此外,本文还介绍了何时以及如何检查任何必要的设备支持,以确保触感反馈效果按预期播放。
创建触感效果的方法有很多种,在选择其中一种方法时,请务必考虑 Android 触感设计原则。下表总结了每种方法的高级属性:
| API Surface | 可用性 | 清晰触感反馈 | 丰富触感反馈 |
|---|---|---|---|
| HapticFeedbackConstants | Android 1.5 及更高版本 (按常量) |
||
| 预定义的 VibrationEffect | Android 10+ | ||
VibrationEffect 构图(首选) |
Android 16+ (26Q4) | ||
VibrationEffect 基元组合 |
Android 11 及更高版本(按常量) | ||
| 开启/关闭、单次振动和波形振动 | Android 1 |
此外,本页介绍的通知 API 可让您自定义来电通知的触感效果。
本页面还介绍了涵盖 API 表面的其他概念:
- 设备是否配备振动器?
- 振幅控制可实现更流畅、更丰富的触感效果,但并非所有设备都支持。
VibrationAttributes()可帮助您根据使用情况对振动进行分类,确保应用适当的用户设置,以免让用户感到意外。
HapticFeedbackConstants
HapticFeedbackConstants 类提供基于操作的常量,以便应用添加在整个设备体验中保持一致的触感反馈,而不是让每个应用针对常见操作提供不同的效果。
兼容性和要求
使用 View.performHapticFeedback 方法和这些常量不需要为应用授予任何特殊权限。它受 View.hapticFeedbackEnabled 属性的约束,如果该属性设置为 false,则会停用视图上的所有触感反馈调用(包括默认调用)。主要相关设置是 View.hapticFeedbackEnabled 属性,如果该属性设置为 false,则会停用视图上的所有触感反馈调用(包括默认调用)。该方法还会遵循用户在系统设置中启用的触感反馈。
唯一需要考虑的兼容性问题是相应操作的特定常量的 SDK 级别。
使用 HapticFeedbackConstants 时,无需提供回退行为。
HapticsFeedbackConstants 的使用情况
如需详细了解如何使用 HapticFeedbackConstants,请参阅为活动添加触感反馈。
预定义 VibrationEffect
VibrationEffect 类提供了多个预定义常量,例如 CLICK、TICK 和 DOUBLE_CLICK。这些效果可能已针对设备进行了优化。
兼容性和要求
播放任何 VibrationEffect 都需要在应用清单中添加 VIBRATE 权限。
使用预定义的 VibrationEffect 时,无需提供回退行为,因为没有设备优化实现的常量会恢复为标准平台回退。
Vibrator.areEffectsSupported 和 Vibrator.areAllEffectsSupported API 用于确定是否存在设备优化实现。即使没有经过优化的实现,仍可使用预定义的效果,并使用标准平台回退。因此,只有当应用想要考虑效果是否针对设备进行了优化时,才需要使用这些 areEffectsSupported API。
效果检查方法可以返回以下三个值之一:
VIBRATION_EFFECT_SUPPORT_YES表示设备已针对此效果优化支持。VIBRATION_EFFECT_SUPPORT_NO表示设备没有优化支持,但仍使用平台回退。VIBRATION_EFFECT_SUPPORT_UNKNOWN表示系统不知道实现是否已优化。
由于 UNKNOWN 值表示检查 API 不可用,因此通常会针对所有效果或不针对任何效果返回该值。这些设备会动态回退。
预定义 VibrationEffect 的使用情况
如需详细了解如何使用预定义的 VibrationEffect,请参阅使用预定义的 VibrationEffect 生成触感反馈。
Envelope VibrationEffect
基于包络的振动可以通过定义一系列控制点来精确控制振动的幅度和频率随时间的变化。这有助于开发者打造更丰富、更细致的触感反馈体验。您可以使用 BasicEnvelopeBuilder 和 WaveformEnvelopeBuilder 类创建这些振动。
兼容性和要求
如需播放任何振动效果,您的应用必须在应用清单中声明 VIBRATE 权限。
如需检查是否支持信封效果,请调用 Vibrator.areEnvelopeEffectsSupported()。
基本信封构建器
为了打造顺畅无缝的触感体验,包络效果必须以强度 \( 0.0 \)开始和结束。该 API 通过将起始强度固定为零来强制执行此操作,如果结束强度不为零,则会抛出异常。此限制可防止因振幅不连续而导致振动中出现不良动态效果,从而对用户的触感感知产生负面影响。
为了在不同设备上提供一致的包络线效果渲染,框架要求支持此功能的设备能够处理控制点之间至少 20 毫秒的最小时长,并且包络线效果至少需要 16 个点。
波形包络线生成器
框架不会修改开发者提供的请求频次和振幅值。不过,该 API 还会将起始振幅固定为零,以创建平滑的过渡。
为了帮助您优化应用的波形包络效果并提供跨设备的兼容性,Android 提供了一些 API 来查询重要的设备功能。这些方法提供有关设备限制的信息,例如控制点之间的最长和最短过渡时长,以及单个效果支持的最大控制点数量:
getMaxSize()- 检索信封效果支持的控制点数量上限。
getMinControlPointDurationMillis()- 检索信封效果中两个控制点之间支持的最短时长(以毫秒为单位)。
getMaxControlPointDurationMillis()- 检索信封效果中两个控制点之间支持的最大时长(以毫秒为单位)。
getMaxDurationMillis()- 检索信封效果支持的最大时长(以毫秒为单位)。
如果效果超出设备的限制(例如允许的控制点过多或时长超出上限),框架会自动调整效果,使其在允许的范围内。此调整过程会尽可能保留设计的原始意图和风格。
Envelope VibrationEffects 的用法
如需详细了解如何创建包络波形效果,请参阅使用包络创建振动波形。
VibrationEffect 乐曲
从 Android 16(2026 年第 4 季度)开始,VibrationEffect.Builder 是用于通过在设计的时间轴上按顺序排列多个触感反馈元素来创作丰富而富有表现力的触感反馈效果的首选 API。它取代了 VibrationEffect.Composition,可提供时间轴锚定调度、原子封装、混合事件支持(将预设和信封相结合)以及内置的自动回退。
组成要素
借助构建工具,您可以按顺序排列以下触感元素:
VibrationEffect.Preset:表示常见短脉冲的预定义触感,例如PRESET_CLICK、PRESET_TICK和PRESET_LOW_TICK。预设取代了VibrationEffect.CompositionAPI 中的短基元。对于更长、连续或逐渐增强的效果(之前由 rise、fall 和其他原语处理),请改用包络线 (PWLE)。可以使用Preset.create(presetId, scale)将预设值缩放为0.0f到1.0f之间的值。VibrationEffect.Envelope:使用BasicEnvelopeBuilder(具有强度和清晰度)或WaveformEnvelopeBuilder(具有频次和振幅)创建的分段线性包络 (PWLE)。信封使用Envelope.create(builder)构建。VibrationEffect.Event:使用getEvents()从现有VibrationEffect中检索的时间轴事件。可以使用addEvents(startTimeShiftMillis, events)添加这些广告,并设置时间轴偏移量。
时间轴安排和验证
每个元素都会添加到构建器中,并使用 startTimeMillis 表示相对于合成开始的时间偏移值(以毫秒为单位):
- 构建时验证:必须按开始时间的严格递增顺序添加元素。构建器会在构建时间通过检查是否达到最短时长(例如预设时长为 1 毫秒,或波封时长为已知时长)来尽力执行验证。如果在 build 时检测到重叠,则会抛出
IllegalArgumentException。 - 播放时间对齐:框架在播放期间尽最大努力提供时间支持。如果上一个事件在下一个预定事件的开始时间到达时仍在执行,框架会自动将后续事件移至下一个最早的可用时段。这样可以防止事件在实际播放中重叠,同时保证不会丢弃任何触感反馈事件。
重复特效
您可以使用 setRepeatingEffect(startTimeMillis, repeatingEffect, durationMillis) 向合成中添加重复效果。配置重复效果后,无法再向构建器添加其他元素。
后备支持
对于由 VibrationEffect.Builder 创建的振动,框架级自动回退支持默认处于启用状态:
- 透明的平台回退:如果设备不支持所请求的
Preset或基本Envelope,框架会在运行时尽最大努力自动将不支持的元素替换为适当的支持的振动。您的应用无需在播放使用VibrationEffect.Builder构建的乐曲之前手动检查设备功能(例如isPresetSupported)。 WaveformEnvelopeBuilder的例外情况:由WaveformEnvelopeBuilder(以赫兹为单位指定绝对物理频率,以 G 为单位指定振幅)创建的包络效果没有自动回退支持。由于高级 PWLE 依赖于特定的硬件频次曲线 (FOAM),因此自动替换它们会损害设计意图。如果设备不支持 PWLE 效果或所请求的频率,则不会播放此类振动。为了实现普遍兼容性,请首选BasicEnvelopeBuilder。
VibrationEffect.Builder 的使用情况
如需查看有关使用 VibrationEffect.Builder 组合效果的代码示例,请参阅使用 VibrationEffect.Builder 创建时间轴锚定合成。
VibrationEffect 基元组合
VibrationEffect 原语组合是使用 VibrationEffect.startComposition API 创建的振动效果。此 API 可让您创建一系列原语。
兼容性和要求
播放任何 VibrationEffect 都需要在应用清单中添加 VIBRATE 权限。
检查基元支持情况
因此,在使用 VibrationEffect.Composition API 时,您必须先使用 Vibrator.arePrimitivesSupported 或 Vibrator.areAllPrimitivesSupported 检查每个图元的支持情况,然后再播放。
可以使用 Vibrator.arePrimitivesSupported 方法检索每个图元的支持。或者,可以使用 Vibrator.areAllPrimitivesSupported 方法一起检查一组基元 - 这相当于对每个基元的支持进行 AND 运算。
VibrationEffect 基元组合的使用
如需详细了解如何使用 VibrationEffect 原语组合,请参阅创建振动原语组合。
开启/关闭、一次性振动和波形振动
Android 上支持的最旧的振动形式是具有可配置时长的简单振动器开启/关闭模式。这些 API 通常与触感设计原则不太一致,因为它们可能会生成嗡嗡的触感;除非万不得已,否则请避免使用它们。
开/关振动最常见的应用场景是通知,无论如何,用户都希望收到一些振动。波形振动还允许模式无限期重复,就像铃声一样。
单次振动模式是指振动一次,持续 N 毫秒。
波形模式有两种:
- 仅限时间信息。此类波形描述了关闭时长和开启时长交替变化的情况。时间安排从关闭状态的持续时间开始。因此,波形模式通常以零值开头,表示立即开始振动。
- 时间安排和振幅。这种波形具有一个额外的振幅数组,用于与每个时间数据相匹配,而不是第一种形式的隐式开/关。不过,务必要检查设备是否支持振幅控制,以确保实现预期的缩放效果。
兼容性和要求
由于开/关振动是最早的振动形式,因此几乎所有配备振动器的设备都支持这种振动,如本页稍后所述。
播放任何 VibrationEffect 或旧版 vibrate 调用都需要在应用清单中添加 VIBRATE 权限。
在波形中使用不同的振幅值时,我们强烈建议您确保设备支持振幅控制。
检查振幅控制支持情况
在没有振幅控制功能的设备上,非零振幅值会向上舍入为 100%,因此务必使用 Vibrator.hasAmplitudeControl 检查是否支持振幅控制。如需了解详情,请参阅振幅控制。
您应仔细考虑在不进行振幅控制的情况下,您的效果是否具有足够的质量。回退到明确设计的开/关振动可能更好。
开启/关闭振动功能的使用情况
在较新的 SDK 级别中,所有振动模式都整合到了一个富有表现力的 VibrationEffect 类中,其中这些简单振动是使用 VibrationEffect.createOneShot 或 VibrationEffect.createWaveform 创建的。
通知 API
自定义应用通知时,您可以使用以下 API 之一将振动模式与每个通知渠道相关联:
- AndroidX
- Android
所有这些形式都采用基本的开/关波形模式(如前所述),其中第一个条目是振动器开启前的延迟时间。
一般概念
有几个概念适用于上文详述的各个 API Surface。
设备是否具有振动器?
您可以从 context.getSystemService(Vibrator.class) 获取非 null 的 Vibrator 类。如果设备没有振动器,对振动 API 的调用不会产生任何影响,因此应用无需根据条件来限制所有触感反馈。不过,如有需要,应用可以调用 hasVibrator() 来确定这是真正的振动器 (true) 还是桩 (false)。
用户是否已停用触感反馈?
某些自定义实现可能需要手动检查用户是否已完全停用 Android 的触控反馈设置,在这种情况下,应禁止触控反馈效果。可以使用 HAPTIC_FEEDBACK_ENABLED 键查询此设置,其中值为零表示已停用。
振动属性
您可以提供振动属性(目前以 AudioAttributes 的形式),以帮助系统了解振动的用途。当应用在后台运行时,如果需要启动振动,则必须使用此权限,因为只有注意力触感支持后台使用。
AudioAttributes 的创建在其类文档中进行了介绍,应将其视为振动而非声音。
作为指南,在大多数情况下,内容类型为 CONTENT_TYPE_SONIFICATION,而使用情况可能为 USAGE_ASSISTANCE_SONIFICATION(用于前台的触感反馈)或 USAGE_ALARM(用于后台的闹铃)等值。音频标志对振动没有影响。
振幅控制
如果振动器具有振幅控制功能,则可以播放不同强度的振动。这是一项重要功能,可用于生成丰富的触感反馈,还可能允许用户控制默认触感强度。
可以通过调用 Vibrator.hasAmplitudeControl 来检查是否支持振幅控制。如果振动器不支持振幅,所有振幅值都将根据其是否为零映射到关闭或开启。因此,如果设备缺乏振幅控制功能,使用不同振幅的丰富触感反馈的应用应考虑停用这些触感反馈。
支持信封效果
支持包络效果的振动器可实现更动态、更细致的振动,从而更精确地控制强度和清晰度,带来更丰富的触感体验。使用 Vibration.areEnvelopeEffectsSupported 确定设备是否支持此功能。如果不是,则会忽略基于波封的振动。