Vibration on Android: How to Control Frequency and Amplitude (Kotlin)

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Control Vibration on Android? From "Buzz" to a Tactile Masterpiece

\n\n

Have you ever wondered why some apps vibrate pleasantly and precisely, while others feel like a neighbor's drill through the wall? It's all about vibration frequency and amplitude. On Stack Overflow, the question "How to make an Android device vibrate with different frequency?" has garnered thousands of views — and for good reason. Developers want not just to "turn on the vibrator," but to create meaningful haptic feedback: a light touch, a pulsing alarm signal, or an imitation of a mechanical button press.

\n\n

In this article, we'll break down how to control vibration on Android using Kotlin. You'll learn what APIs exist, how they've evolved from Android 8 to Android 14, and which approach to choose for your project. Let's go!

\n\n

A Brief History Lesson: From Vibrator to VibratorManager

\n\n

For a long time, Android developers used the Vibrator class and the vibrate(long milliseconds) method. Simple, but sad: no control over frequency. With the arrival of Android 8 (API 26), Google introduced VibrationEffect — a powerful tool for creating complex vibration patterns. And in Android 12 (API 31), they added VibratorManager, which allows you to control multiple vibrators (for example, on foldable devices).

\n\n

Today we have three main approaches:

\n
    \n
  • Vibrator + VibrationEffect (API 26+) — basic, but flexible.
  • \n
  • VibratorManager (API 31+) — modern, for multi-vibrator devices.
  • \n
  • Legacy Vibrator.vibrate() — only for backward compatibility.
  • \n
\n\n

We'll focus on the first two, as they provide control over frequency and amplitude.

\n\n

Preparation: Vibration Permission

\n\n

Before you trigger an "earthquake," don't forget to add the permission to AndroidManifest.xml:

\n
<uses-permission android:name="android.permission.VIBRATE" />
\n\n

Without it, your code will simply be ignored — no errors, but no vibration either.

\n\n

Method 1: VibrationEffect — Controlling Frequency and Amplitude (API 26+)

\n\n

The VibrationEffect class allows you to create vibration with a specified frequency (via amplitude) and duration. Frequency in Android is not set directly in hertz — instead, amplitude (0–255) is used, which is hardware-converted into frequency. The higher the amplitude, the more intense the vibration.

\n\n

Simple Vibration with Amplitude

\n\n
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator\n\n// Vibration for 500 ms with maximum amplitude (255)\nval effect = VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)\nvibrator.vibrate(effect)
\n\n

Vibration with Different Frequency (Amplitude)

\n\n

Want a weak vibration? Specify an amplitude of 50:

\n
val weakVibration = VibrationEffect.createOneShot(300, 50)\nvibrator.vibrate(weakVibration)
\n\n

Amplitude 255 is maximum, 1 is barely noticeable. Experiment!

\n\n

Patterns: Vibration with Pauses

\n\n

Sometimes you need not just a "buzz," but a pulse. Use createWaveform:

\n
val timings = longArrayOf(0, 200, 100, 300)  // pause, vibration, pause, vibration\nval amplitudes = intArrayOf(0, 200, 0, 150)  // amplitude for each stage\n\nval pattern = VibrationEffect.createWaveform(timings, amplitudes, -1)  // -1 = do not repeat\nvibrator.vibrate(pattern)
\n\n

The first element of timings is the initial delay. Usually set to 0. amplitudes must be the same length. If you pass null instead of the amplitude array, the maximum amplitude will be used for all stages.

\n\n

Method 2: VibratorManager — For Modern Devices (API 31+)

\n\n

Starting with Android 12, it is recommended to use VibratorManager

Blogs

Book Recommendations