Question
How to Vibrate an Android Device in Java: Vibrator and VibrationEffect
Question
I am developing an Android application and want the device to vibrate when a specific action occurs. How can I trigger vibration in Android?
I would also like to understand how vibration duration and patterns work, and whether it is possible to control vibration strength or frequency on supported devices.
Short Answer
By the end of this page, you will understand how to make an Android device vibrate from an Android app, which permission is required, how to use Vibrator and VibrationEffect, how vibration patterns work, and what hardware limitations affect amplitude and frequency control.
Concept
In Android, vibration is handled through the system vibration service. Your app does not directly control the motor hardware. Instead, it requests vibration through APIs such as Vibrator.
The main ideas are:
- Vibration is a system service: you ask Android for the vibrator service.
- You usually need the
VIBRATEpermission in your manifest. - Modern Android uses
VibrationEffectfor one-shot vibrations and patterns. - Hardware support varies: not every device supports the same vibration features.
A simple vibration can be triggered for a duration such as 200 milliseconds. More advanced behavior can include:
- a single short buzz
- a pattern like pause-buzz-pause-buzz
- custom amplitude on supported devices
About different frequency: in normal Android app development, you usually cannot directly control vibration frequency in the way you control sound frequency. Most apps can control:
- duration
- pattern
- sometimes amplitude on supported devices
Frequency is generally tied to the hardware and lower-level system behavior, not exposed as a normal high-level app setting.
This matters in real programming because vibration is often used for:
- user feedback after button presses
- alerts and notifications
- error or success feedback
- accessibility and haptic guidance
Using the correct API keeps your app compatible with modern Android versions and avoids deprecated approaches.
Mental Model
Think of Android vibration like asking a building receptionist to ring a buzzer for you.
- Your app is the visitor.
- Android is the receptionist.
- The vibration motor is the buzzer hardware.
You do not touch the buzzer directly. You ask Android:
- buzz once for 200 ms
- buzz in a pattern
- buzz with a certain strength if supported
But you usually cannot say, "buzz at exactly this physical frequency," because that depends on the buzzer hardware itself.
Syntax and Examples
1. Add the permission
In AndroidManifest.xml:
<uses-permission android:name="android.permission.VIBRATE" />
2. Basic vibration in Java
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(300, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
vibrator.vibrate(300);
}
}
What this does
- Gets the system vibrator service
- Checks that the device actually has a vibrator
- Uses the modern API on Android 8.0+ (
Oreo) - Falls back to the older method on earlier Android versions
3. Vibration pattern example
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator()) {
long[] pattern = {0, 200, 100, 300};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1);
vibrator.vibrate(effect);
} else {
vibrator.vibrate(pattern, -1);
}
}
Pattern meaning
The array means:
0: start immediately200: vibrate for 200 ms100: pause for 100 ms300: vibrate for 300 ms
The second argument -1 means do not repeat.
4. Custom amplitude example
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator()) {
VibrationEffect effect = VibrationEffect.createOneShot(250, 128);
vibrator.vibrate(effect);
}
}
Amplitude notes
- Valid amplitude values are typically
1to255 VibrationEffect.DEFAULT_AMPLITUDElets Android decide- Not all devices support meaningful amplitude control
5. In an onClick listener
button.setOnClickListener(v -> {
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
vibrator.vibrate(100);
}
}
});
This is a common way to provide short haptic feedback after a user action.
Step by Step Execution
Consider this example:
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
vibrator.vibrate(200);
}
}
Here is what happens step by step:
getSystemService(Context.VIBRATOR_SERVICE)asks Android for access to the vibration system.- The result is cast to
Vibratorso Java can use vibrator methods. vibrator != nullchecks that Android returned a service object.vibrator.hasVibrator()checks whether the current device actually supports vibration.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Ochecks the Android version.- If the device runs Android 8.0 or later, the code creates a
VibrationEffectobject. createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE)means vibrate once for 200 milliseconds using the system's default strength.vibrator.vibrate(...)sends the request to Android.- On older versions,
vibrator.vibrate(200)uses the legacy API.
Execution trace example
If a user presses a button:
- the click listener runs
- your app requests the vibrator service
- Android checks the device capability
- Android triggers the motor for the requested duration
- the user feels a short buzz
Real World Use Cases
Vibration is commonly used in Android apps for lightweight physical feedback.
Common use cases
- Button feedback: confirm that a tap or long press was recognized
- Form validation: give a short buzz when input is invalid
- Timers and alarms: notify the user even when sound is off
- Games: provide impact feedback for collisions or damage
- Messaging apps: signal incoming messages or calls
- Accessibility features: help users understand state changes through touch
Example scenarios
Invalid PIN entry
if (!isPinCorrect) {
vibrateError();
}
A short pattern can signal an error without requiring the user to look at the screen.
Task completion
if (taskFinished) {
vibrateSuccess();
}
A brief one-shot vibration gives immediate feedback.
Repeating reminder pattern
Apps such as timers may use patterns for stronger notification behavior, though many notification use cases are better handled through Android's notification system.
Real Codebase Usage
In real Android projects, vibration is usually wrapped in a helper method or utility class instead of being duplicated everywhere.
Common pattern: helper method
private void vibrateShort() {
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator == null || !vibrator.hasVibrator()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
vibrator.vibrate(100);
}
}
This uses a guard clause:
- if the vibrator service is unavailable
- or the device has no vibrator
- return early
That keeps the rest of the code cleaner.
Common pattern: event-based feedback
Developers often call vibration methods from:
- click handlers
- validation logic
- error handling branches
- notification flows
- game event systems
Common pattern: semantic methods
Instead of calling raw vibration code everywhere, developers create methods like:
vibrateSuccess()vibrateError()vibrateWarning()
Example:
private void vibrateError() {
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator == null || !vibrator.hasVibrator()) return;
long[] pattern = {0, 100, 80, 100};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createWaveform(pattern, -1));
} else {
vibrator.vibrate(pattern, -1);
}
}
This makes the code easier to maintain and more expressive.
Validation and fallback
Real apps also consider:
- Android version differences
- missing hardware
- whether the UX really needs vibration
- not overusing haptics so the app does not feel annoying
Common Mistakes
1. Forgetting the manifest permission
Broken example:
<!-- Missing VIBRATE permission -->
Fix:
<uses-permission android:name="android.permission.VIBRATE" />
2. Using deprecated vibration code only
Broken example:
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(500);
This may still work on older devices, but modern Android prefers VibrationEffect on Android 8.0+.
Fix:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
vibrator.vibrate(500);
}
3. Not checking for null or hardware support
Broken example:
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(200);
Fix:
if (vibrator != null && vibrator.hasVibrator()) {
// vibrate here
}
4. Assuming frequency can be freely controlled
Beginners often expect vibration to work like audio synthesis. In standard Android app APIs, frequency control is generally not exposed in that way.
What you can reliably work with:
- duration
- pattern
- amplitude on supported devices
5. Overusing vibration
Too much vibration can make an app feel distracting or unpleasant.
Avoid:
- vibrating on every tiny UI update
- long unnecessary vibrations
- repeated buzzing for low-importance actions
6. Confusing amplitude with frequency
Amplitude means strength. Frequency means how fast something oscillates.
Android's common high-level APIs may let you influence amplitude, but not direct physical frequency in the normal app layer.
Comparisons
| Concept | What it controls | Supported broadly? | Best use |
|---|---|---|---|
vibrate(duration) | Duration only | Older API style | Legacy compatibility |
VibrationEffect.createOneShot() | Duration + optional amplitude | Modern Android | Simple single buzz |
VibrationEffect.createWaveform() | Pattern + optional repeat | Modern Android | Multi-step haptic patterns |
| Amplitude | Strength of vibration | Device-dependent | Stronger/weaker feedback |
| Frequency | Physical motor oscillation rate | Usually not app-controlled | Generally not available to normal apps |
createOneShot() vs createWaveform()
| Method | Use when | Example |
|---|---|---|
createOneShot() | You want one short vibration | button tap feedback |
createWaveform() | You want multiple buzz/pause steps | error or alert pattern |
Legacy API vs modern API
| Approach | Pros | Cons |
|---|---|---|
Legacy vibrate(long) | Very simple | Deprecated for newer Android styles |
Modern VibrationEffect | Clearer, more flexible, supports amplitude | Requires version check |
Cheat Sheet
Quick reference
Manifest permission
<uses-permission android:name="android.permission.VIBRATE" />
Get the vibrator service
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
Check support
if (vibrator != null && vibrator.hasVibrator()) {
// safe to request vibration
}
One-shot vibration
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
vibrator.vibrate(200);
}
Pattern vibration
long[] pattern = {0, 200, 100, 300};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createWaveform(pattern, -1));
} else {
vibrator.vibrate(pattern, -1);
}
Important rules
- Add
VIBRATEpermission in the manifest - Check
hasVibrator()before vibrating - Use
VibrationEffecton Android 8.0+ - Use
-1in waveform repeat to avoid repeating - Amplitude may not work equally on all devices
- Direct frequency control is generally not available
Common values
- duration: milliseconds, like
100,200,500 - amplitude: usually
1to255 - default amplitude:
VibrationEffect.DEFAULT_AMPLITUDE
FAQ
Can I vibrate an Android phone without permission?
Usually you should declare android.permission.VIBRATE in the manifest. That is the standard way to use the vibration API.
How do I make Android vibrate for 1 second?
Use 1000 milliseconds:
vibrator.vibrate(VibrationEffect.createOneShot(1000, VibrationEffect.DEFAULT_AMPLITUDE));
For older versions, use vibrator.vibrate(1000).
Can I control vibration frequency in Android?
Usually not directly through normal app APIs. You can generally control duration, pattern, and sometimes amplitude, but not the physical vibration frequency.
What is the difference between amplitude and duration?
- Duration is how long the vibration lasts.
- Amplitude is how strong the vibration feels.
Why is my Android vibration code not working?
Common reasons include:
- missing
VIBRATEpermission - no vibrator hardware on the device
- no version check for
VibrationEffect - testing on a device or emulator without meaningful haptic support
Should I use vibrate(long) or VibrationEffect?
Use VibrationEffect on Android 8.0 and above. Keep the old method only as a fallback for older Android versions.
Mini Project
Description
Build a simple Android screen with three buttons: Short Buzz, Error Pattern, and Success Buzz. This project demonstrates how to trigger one-shot vibration, use a waveform pattern, and safely handle Android version differences and missing hardware support.
Goal
Create a small Android activity that gives different vibration feedback for different user actions.
Requirements
- Add the vibration permission to the Android manifest.
- Show three buttons in the activity layout.
- Make the first button trigger a short one-shot vibration.
- Make the second button trigger a multi-step error pattern.
- Make the third button trigger a slightly longer success vibration.
- Check that the device supports vibration before trying to vibrate.
Keep learning
Related questions
Accessing Kotlin Extension Functions from Java
Learn how Kotlin extension functions are compiled and how to call them correctly from Java with clear examples and common pitfalls.
Add a Maven Repository URL in Gradle Kotlin DSL (build.gradle.kts)
Learn how to add Maven Central and a custom Maven repository URL in Gradle Kotlin DSL using build.gradle.kts syntax.
Allow HTTP and HTTPS in Android 9 Pie with Network Security Configuration
Learn how Android 9 Pie handles cleartext HTTP traffic and how to allow HTTP and HTTPS safely using network security config.