在 Android 中,控制手机振动主要通过 Vibrator 服务(或 VibrationEffect API)来实现,从 Android 8.0 (Oreo, API 26) 开始,Google 推荐使用 VibrationEffect,因为它提供了更丰富、更精确的控制能力,旧版本则使用 vibrate(long milliseconds) 方法。

核心 API 介绍
Vibrator 服务
这是振动功能的核心,获取它的实例有两种方式:
- 旧方式 (适用于所有版本,但已废弃):
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
- 新方式 (推荐, API 31+):
VibratorManager vibratorManager = (VibratorManager) getSystemService(Context.VIBRATOR_MANAGER_SERVICE); Vibrator vibrator = vibratorManager.getDefaultVibrator();
新方式更好地管理了振动权限,并且是未来的趋势。
VibrationEffect (API 26+)
这是 Android 8.0 引入的新 API,用于描述一个复杂的振动效果,它比旧的 vibrate(long) 方法更强大。
主要的构造方法有:

-
VibrationEffect.createOneShot(long milliseconds, int amplitude)- 功能:创建一个只振动一次的效果。
- 参数:
milliseconds(long): 振动的持续时间,单位是毫秒。amplitude(int): 振动的振幅(强度)。- 范围:
VibrationEffect.DEFAULT_AMPLITUDE(默认强度) 到255(最大强度)。 - 特殊值:
VibrationEffect.DEFAULT_AMPLITUDE: 使用系统默认的振动强度。VibrationEffect.AMPLITUDE_OFF: 振幅为0,相当于不振动。
- 范围:
- 示例:
// 振动500毫秒,使用默认强度 VibrationEffect effect = VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE); vibrator.vibrate(effect);
-
VibrationEffect.createWaveform(long[] timings, int[] amplitudes, int repeat)-
功能:创建一个由多个“开启-关闭”周期组成的复杂波形振动,这是实现“滴滴-滴滴”这类模式的关键。
-
参数:
(图片来源网络,侵删)timings(long[]): 一个交替的时长数组,单位是毫秒。timings[0]: 第一次振动的持续时间。timings[1]: 第一次停顿的持续时间。timings[2]: 第二次振动的持续时间。timings[3]: **第二次停顿的持续时间`。- ... 以此类推。
amplitudes(int[]): 一个与timings长度相同的振幅数组。amplitudes[0]: 第一次振动的强度。amplitudes[1]: 第一次停顿的强度(必须是0)。amplitudes[2]: 第二次振动的强度。- ... 以此类推。
- 注意: 停顿对应的振幅必须为0。
repeat(int): 重复模式。-1: 不重复,振动完timings数组中的所有周期后停止。0: 无限循环,会一直重复timings数组中的周期,直到你手动调用cancel()。> 0: 从timings数组的指定索引处开始重复。repeat=2表示在振动完前两个周期后,会从timings[2]开始重复。
-
示例: 实现“振动100ms,停顿50ms,再振动200ms,然后停止”的效果。
long[] timings = {100, 50, 200}; // 振动100ms -> 停顿50ms -> 振动200ms int[] amplitudes = {VibrationEffect.DEFAULT_AMPLITUDE, 0, VibrationEffect.DEFAULT_AMPLITUDE}; int repeat = -1; // 不重复 VibrationEffect effect = VibrationEffect.createWaveform(timings, amplitudes, repeat); vibrator.vibrate(effect);
-
-
预定义效果 (API 29+)
VibrationEffect.EFFECT_CLICK: 模拟点击效果(短、轻)。VibrationEffect.EFFECT_DOUBLE_CLICK: 模拟双击效果。VibrationEffect.EFFECT_HEAVY_CLICK: 模拟重击效果(长、重)。VibrationEffect.EFFECT_TICK: 模拟表盘转动效果(非常短)。- 使用:
// 使用预定义的点击效果 VibrationEffect effect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK); vibrator.vibrate(effect);
新旧 API 对比与代码示例
旧版 API (API 25 及以下)
// 1. 获取 Vibrator 实例
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
// 2. 检查是否有硬件振动器
if (vibrator.hasVibrator()) {
// 简单振动:振动 500 毫秒
vibrator.vibrate(500);
// 带重复的振动:振动 500ms,停顿 1000ms,然后无限循环
// 注意:这个方法在 API 26 后已废弃
long[] pattern = {0, 500, 1000}; // 开始延迟0ms, 振动500ms, 停顿1000ms
vibrator.vibrate(pattern, 0); // 0 表示从 pattern 的第一个索引(即振动500ms)开始重复
}
新版 API (推荐, API 26+)
// 1. 获取 VibratorManager 和 Vibrator 实例
VibratorManager vibratorManager = (VibratorManager) getSystemService(Context.VIBRATOR_MANAGER_SERVICE);
Vibrator vibrator = vibratorManager.getDefaultVibrator();
// 2. 检查权限和硬件支持
if (vibrator.hasVibrator()) {
// 方式一:使用 createOneShot
VibrationEffect oneShotEffect = VibrationEffect.createOneShot(400, VibrationEffect.DEFAULT_AMPLITUDE);
vibrator.vibrate(oneShotEffect);
// 方式二:使用 createWaveform 实现复杂模式
// 模式:振动100ms -> 停顿50ms -> 振动100ms -> 停顿50ms -> 振动100ms,然后停止
long[] timings = {100, 50, 100, 50, 100};
int[] amplitudes = {VibrationEffect.DEFAULT_AMPLITUDE, 0, VibrationEffect.DEFAULT_AMPLITUDE, 0, VibrationEffect.DEFAULT_AMPLITUDE};
VibrationEffect waveformEffect = VibrationEffect.createWaveform(timings, amplitudes, -1); // -1 表示不重复
vibrator.vibrate(waveformEffect);
// 方式三:使用预定义效果 (API 29+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
VibrationEffect clickEffect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK);
vibrator.vibrate(clickEffect);
}
}
重要注意事项
权限问题
-
普通振动 (旧版): 在
AndroidManifest.xml中声明VIBRATE权限即可。<uses-permission android:name="android.permission.VIBRATE" />
这个权限在安装时自动授予,不需要运行时请求。
-
精确振动 (新版, API 26+): 使用
VibrationEffect需要VIBRATE权限,并且从 Android 12 (API 31) 开始,VIBRATE权限变成了运行时权限,如果你的应用的目标 API 级别是 31 或更高,你必须在代码中动态请求这个权限。// 在 Activity 或 Fragment 中请求权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.VIBRATE}, MY_VIBRATION_REQUEST_CODE); }
检查硬件支持
在调用任何振动方法之前,务必使用 vibrator.hasVibrator() 检查设备是否有物理振动器,很多平板电脑或模拟器就没有。
取消振动
当你启动了一个需要重复的振动效果后(repeat=0),如果你想在它自然结束之前停止它,可以调用:
vibrator.cancel();
这是一个非常好的习惯,可以防止在 Activity 销毁或暂停时手机持续振动。
性能与用户体验
- 不要过度使用振动:频繁或长时间的振动会耗电并让用户感到烦躁。
- 提供设置选项:允许用户在应用设置中关闭振动功能,尊重用户的选择。
- 关联上下文:确保振动效果与应用内的操作相关联(如点击按钮、收到通知),这样振动才有意义。
参数总结表
| API/方法 | 参数名 | 类型 | 描述 | 示例值 |
|---|---|---|---|---|
| 旧版 | vibrate(long ms) |
long |
振动总时长 | 500 (500ms) |
| 旧版 | vibrate(long[] pattern, int repeat) |
long[] |
振动-停顿-振动...的时长模式 | {0, 500, 1000} |
int |
重复模式 | 0 (从模式开始循环) |
0 |
|
| 新版 | createOneShot(long ms, int amp) |
long |
振动总时长 | 500 |
int |
振幅 | VibrationEffect.DEFAULT_AMPLITUDE |
VibrationEffect.DEFAULT_AMPLITUDE |
|
| 新版 | createWaveform(long[] timings, int[] amps, int repeat) |
long[] |
振动-停顿-振动...的时长数组 | {100, 50, 200} |
int[] |
对应的振幅数组 | {DEFAULT, 0, DEFAULT} |
||
int |
重复模式 | -1 (不重复) |
-1 |
|
| 新版 | createPredefined(int effectId) |
int |
预定义效果ID | VibrationEffect.EFFECT_CLICK |
| 通用 | cancel() |
(无) | 立即停止振动 | - |
| 通用 | hasVibrator() |
(无) | 检查是否有振动硬件 | true / false |
希望这份详细的解析能帮助你完全理解 Android 振动功能的参数和使用!
