本部分简要介绍了 Android 中提供的各种触感 API。本文还介绍了何时以及如何检查任何必要的设备支持,以确保触感效果按预期播放。
创建触感效果的方法有很多种,在选择其中一种方法时,请务必考虑 Android 触感设计原则。下表总结了每种方法的高级属性:
| API Surface | 可用性 | 清晰触感反馈 | 丰富触感反馈 |
|---|---|---|---|
| HapticFeedbackConstants | Android 1.5 及更高版本 (按常量) |
||
| 预定义的 VibrationEffect | Android 10+ | ||
| 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 组成
VibrationEffect 振动效果是使用 VibrationEffect.startComposition API 创建的振动效果。此 API 可通过创建具有自定义延迟和强度的基元序列来实现富有表现力的丰富触感反馈。不过,请特别注意确保设备支持所组合的功能,以免出现不一致的总体体验。
兼容性和要求
播放任何 VibrationEffect 都需要在应用清单中添加 VIBRATE 权限。
并非所有设备都支持合成 API 的所有功能,因此务必确保 primitive 可用。
检查振动原语支持
可以使用 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 表面。
设备是否具有振动器?
您可以从 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 确定设备是否支持此功能。如果不是,则会忽略基于信封的振动。