Зачем управлять вибрацией на Android? От «дзынь» до тактильного шедевра
Вы когда-нибудь задумывались, почему одни приложения вибрируют приятно и точно, а другие — как дрель соседа за стеной? Всё дело в частоте и амплитуде вибрации. На Stack Overflow вопрос «How to make an Android device vibrate with different frequency?» набрал тысячи просмотров — и это не случайно. Разработчики хотят не просто «включить вибро», а создать осмысленную тактильную обратную связь: лёгкое касание, пульсирующий сигнал тревоги или имитацию нажатия механической кнопки.
В этой статье мы разберём, как управлять вибрацией на Android с помощью Kotlin. Вы узнаете, какие API существуют, как они эволюционировали от Android 8 до Android 14, и какой подход выбрать для вашего проекта. Поехали!
Краткий экскурс в историю: от Vibrator до VibratorManager
Долгое время Android-разработчики использовали класс Vibrator и метод vibrate(long milliseconds). Просто, но грустно: никакого контроля над частотой. С появлением Android 8 (API 26) Google представил VibrationEffect — мощный инструмент для создания сложных вибрационных паттернов. А в Android 12 (API 31) добавили VibratorManager, который позволяет управлять несколькими вибраторами (например, на складных устройствах).
Сегодня у нас три основных подхода:
- Vibrator + VibrationEffect (API 26+) — базовый, но гибкий.
- VibratorManager (API 31+) — современный, для мультивибраторных устройств.
- Устаревший Vibrator.vibrate() — только для обратной совместимости.
Мы сосредоточимся на двух первых, так как они дают контроль над частотой и амплитудой.
Подготовка: разрешение на вибрацию
Прежде чем запускать «землетрясение», не забудьте добавить разрешение в AndroidManifest.xml:
<uses-permission android:name="android.permission.VIBRATE" />
Без него ваш код просто проигнорируют — никаких ошибок, но и вибрации не будет.
Способ 1: VibrationEffect — контроль частоты и амплитуды (API 26+)
Класс VibrationEffect позволяет создавать вибрацию с заданной частотой (через амплитуду) и длительностью. Частота в Android не задаётся напрямую в герцах — вместо этого используется амплитуда (0–255), которая аппаратно преобразуется в частоту. Чем выше амплитуда, тем интенсивнее вибрация.
Простая вибрация с амплитудой
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
// Вибрация 500 мс с максимальной амплитудой (255)
val effect = VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)
vibrator.vibrate(effect)
Вибрация с разной частотой (амплитудой)
Хотите слабую вибрацию? Укажите амплитуду 50:
val weakVibration = VibrationEffect.createOneShot(300, 50)
vibrator.vibrate(weakVibration)
Амплитуда 255 — максимальная, 1 — едва заметная. Экспериментируйте!
Паттерны: вибрация с паузами
Иногда нужно не просто «дзынь», а пульсацию. Используйте createWaveform:
val timings = longArrayOf(0, 200, 100, 300) // пауза, вибрация, пауза, вибрация
val amplitudes = intArrayOf(0, 200, 0, 150) // амплитуда для каждого этапа
val pattern = VibrationEffect.createWaveform(timings, amplitudes, -1) // -1 = не повторять
vibrator.vibrate(pattern)
Первый элемент timings — начальная задержка. Обычно ставят 0. amplitudes должны быть той же длины. Если передать null вместо массива амплитуд, будет использоваться максимальная амплитуда на всех этапах.
Способ 2: VibratorManager — для современных устройств (API 31+)
Начиная с Android 12, рекомендуется использовать VibratorManager. Он даёт доступ ко всем вибраторам устройства. На обычных смартфонах вибратор один, но на складных или игровых устройствах их может быть несколько.
Получаем VibratorManager
val vibratorManager = getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
val vibrator = vibratorManager.defaultVibrator
Дальше работаем с vibrator так же, как в первом способе. Но есть нюанс: VibratorManager позволяет комбинировать вибраторы.
Вибрация с частотой через VibrationEffect.Composition
Для точного управления частотой (в герцах) используйте VibrationEffect.startComposition() (доступно с API 33). Это экспериментальный API, но он даёт максимальный контроль:
val composition = VibrationEffect.startComposition()
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1.0f, 100) // амплитуда 1.0, частота 100 Гц
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f, 200) // амплитуда 0.5, частота 200 Гц
.compose()
vibrator.vibrate(composition)
Здесь PRIMITIVE_CLICK и PRIMITIVE_TICK — встроенные примитивы вибрации. Второй параметр — интенсивность (0.0–1.0), третий — частота в герцах. Не все устройства поддерживают произвольную частоту, поэтому проверяйте через vibrator.hasAmplitudeControl().
Сравнение подходов: что выбрать?
Сведём всё в таблицу для наглядности:
- Vibrator + VibrationEffect (API 26+):
✅ Работает на большинстве устройств (Android 8+).
✅ Контроль амплитуды (0–255).
❌ Нет прямого управления частотой в Гц.
❌ Не поддерживает несколько вибраторов. - VibratorManager (API 31+):
✅ Доступ к нескольким вибраторам.
✅ Поддержка Composition (частота в Гц) на API 33+.
❌ Требует Android 12+. - Старый Vibrator.vibrate(long):
❌ Нет контроля амплитуды и частоты.
❌ Deprecated с API 26.<