This document introduces the various haptics APIs available in Android, explaining how to create different haptic effects and how to check for necessary device support. keywords_public: > Android, haptics, APIs, vibration, HapticFeedbackConstants, VibrationEffect, envelope haptics, haptic feedback, notification, amplitude control
This section gives an introduction to the various haptics APIs available in Android. It also covers when and how to check for any device support necessary to ensure your haptic effects play as you intend.
There are several different ways to create haptic effects, and it's important to consider Android haptics design principles when choosing among them. The following table summarizes these high level attributes of each approach:
- Availability is particularly important when planning behavior fallback, and needs to be combined with checking individual device support.
- Clear haptics are crisp and clean sensations that are less jarring for users.
- Rich haptics have greater expressiveness and often require more feature-rich hardware.
| API surface | Availability | Clear haptics | Rich haptics |
|---|---|---|---|
| HapticFeedbackConstants | Android 1.5+ (per constant) |
||
| Predefined VibrationEffect | Android 10+ | ||
VibrationEffect composition (Preferred) |
Android 16+ (26Q4) | ||
VibrationEffect primitives composition |
Android 11+ (per constant) | ||
| On/off, one-shot and waveform vibrations | Android 1 |
Additionally, notification APIs, described on this page, lets you customize the haptic effects that play for incoming notifications.
Also described on this page are additional concepts that span the API surfaces:
- Does the device have a vibrator?
- Amplitude control allows smoother, richer haptic effects, but isn't supported by all devices.
VibrationAttributes()helps you classify vibrations based on usage, ensuring the appropriate user settings are applied to avoid surprising the user.
HapticFeedbackConstants
The HapticFeedbackConstants class provides action-based constants to allow
apps to add haptic feedback that's consistent across the device experience,
rather than each app having different effects for common actions.
Compatibility and requirements
Using the View.performHapticFeedback method with these constants
doesn't require any special permissions for the app. It is subject to the
View.hapticFeedbackEnabled property, which if set to false will disable
all haptic feedback calls on the view, including default ones.The primary
related setting the View.hapticFeedbackEnabled property, which if set to
false will disable all haptic feedback calls on the view, including default
ones. The method also honours the user's system setting for enabling touch
feedback.
The only compatibility consideration is the SDK-level of the specific constant for the action.
There is no need to provide fallback behavior when using
HapticFeedbackConstants.
Usage of HapticsFeedbackConstants
For details on using HapticFeedbackConstants, see Add haptic feedback to
events.
Predefined VibrationEffect
The VibrationEffect class
provides several predefined constants such as CLICK, TICK and
DOUBLE_CLICK. These effects may be optimized for the device.
Compatibility and requirements
Playing any VibrationEffect requires the VIBRATE permission in the app
manifest.
There is no need to provide fallback behavior when using predefined
VibrationEffect, as constants that don't have a device-optimized
implementation revert to a standard platform fallback.
The Vibrator.areEffectsSupported and Vibrator.areAllEffectsSupported
APIs are for determining if there is a device-optimized implementation.
Predefined effects can still be used without an optimized implementation, and
uses the standard platform fallback. Consequently, these
areEffectsSupported APIs are only needed if an application wants to take into
consideration whether the effect is optimized for the device or not.
The effect-checking methods can return one of three values:
VIBRATION_EFFECT_SUPPORT_YESindicates that the device has optimized support for this effect.VIBRATION_EFFECT_SUPPORT_NOindicates that the device doesn't have optimized support, but still uses the platform fallback.VIBRATION_EFFECT_SUPPORT_UNKNOWNindicates the system doesn't know if the implementation is optimized or not.
As the UNKNOWN value indicates the checking API is unavailable, it's typically
returned for all effects or none of them. These devices fall back dynamically.
Usage of predefined VibrationEffect
For details on using a predefined VibrationEffect, see
Use a predefined VibrationEffect to generate haptic
feedback.
Envelope VibrationEffect
Envelope based vibrations allow for precise control of the vibration's amplitude
and frequency over time by defining a sequence of control points. This enables
developers to craft richer and more nuanced haptic feedback experiences. These
vibrations can be created using the BasicEnvelopeBuilder and
WaveformEnvelopeBuilder classes.
Compatibility and requirements
To play any vibration effects, your app must declare the VIBRATE permission in
the app manifest.
To check for envelope effects support, call
Vibrator.areEnvelopeEffectsSupported().
Basic Envelope Builder
To create a smooth and seamless haptic experience, envelope effects must start and end with an intensity of \( 0.0 \). The API enforces this by fixing the start intensity at zero and throws an exception if the end intensity isn't zero. This constraint prevents undesirable dynamic effects in the vibrations due to discontinuities in the amplitude that can negatively impact the user's haptic perception.
To provide consistent envelope effect rendering across devices, the framework requires that devices supporting this feature can handle a minimum duration of 20 ms between control points and at least 16 points for envelope effects.
Waveform Envelope Builder
The framework doesn't modify the requested frequency and amplitude values provided by the developer. However, the API also fixes the start amplitude at zero to create smooth transitions.
To help you optimize your app's waveform envelope effects and provide compatibility across devices, Android provides APIs for querying important device capabilities. These methods provide information about the device's limitations, such as the maximum and minimum transition duration between control points and maximum number of control points supported for a single effect:
getMaxSize()- Retrieves the maximum number of control points supported for an envelope effect.
getMinControlPointDurationMillis()- Retrieves the minimum duration supported, in milliseconds, between two control points within an envelope effect.
getMaxControlPointDurationMillis()- Retrieves the maximum duration supported, in milliseconds, between two control points within an envelope effect.
getMaxDurationMillis()- Retrieves the maximum duration supported for an envelope effect, in milliseconds.
If an effect exceeds the device's limitations—such as allowing too many control points or a duration exceeding the maximum—the framework automatically adjusts the effect to fit within the allowed boundaries. This adjustment process tries to preserve the original intent and feel of the design as much as possible.
Usage of Envelope VibrationEffects
For details on creating envelope waveform effects, see create vibration waveform with envelopes.
VibrationEffect composition
Starting in Android 16 (26Q4), VibrationEffect.Builder is the preferred
API for composing rich, expressive haptic effects by sequencing multiple haptic
elements along a designed timeline. It supersedes
VibrationEffect.Composition by
offering timeline anchored scheduling, atomic encapsulation, mixed event support
(combining presets and envelopes), and built-in automatic fallback.
Building blocks
The builder lets you sequence the following haptic elements:
VibrationEffect.Preset: Predefined haptic sensations representing common short pulses, such asPRESET_CLICK,PRESET_TICK, andPRESET_LOW_TICK. Presets supersede the short primitives from theVibrationEffect.CompositionAPI. For longer, continuous, or ramping effects (previously handled by rise, fall and other primitives), use envelopes (PWLE) instead. Presets can be scaled from0.0fto1.0fusingPreset.create(presetId, scale).VibrationEffect.Envelope: Piecewise linear envelopes (PWLEs) created using eitherBasicEnvelopeBuilder(with intensity and sharpness) orWaveformEnvelopeBuilder(with frequency and amplitude). Envelopes are constructed usingEnvelope.create(builder).VibrationEffect.Event: Timeline events retrieved from an existingVibrationEffectusinggetEvents(). These can be added with a timeline offset usingaddEvents(startTimeShiftMillis, events).
Timeline scheduling and validation
Each element is added to the builder with a startTimeMillis representing the
time offset (in milliseconds) from the start of the composition:
- Build-time validation: Elements must be added in strictly increasing
order of their start times. The builder performs best-effort validation at
build time by checking against the minimum duration (such as 1 ms for
presets or known durations for envelopes). If an overlap is detected at
build time, an
IllegalArgumentExceptionis thrown. - Playback timing alignment: The framework provides best-effort timing support during playback. If a previous event is still executing when the next scheduled event's start time arrives, the framework automatically shifts the subsequent event to the next earliest available slot. This prevents events from overlapping in physical playback while guaranteeing that no haptic events are dropped.
Repeating effects
A repeating effect can be added to the composition using
setRepeatingEffect(startTimeMillis, repeatingEffect, durationMillis). Once a
repeating effect is configured, no additional elements may be added to the
builder.
Fallback support
Framework-level automatic fallback support is default enabled for vibration
created by VibrationEffect.Builder:
- Transparent platform fallback: If a device doesn't support a
requested
Presetor basicEnvelope, the framework automatically substitutes the unsupported element with an appropriate supported vibration at runtime with best effort. Your app doesn't need to manually check device capabilities (such asisPresetSupported) before playing compositions built withVibrationEffect.Builder. - Exception for
WaveformEnvelopeBuilder: Envelope effects created byWaveformEnvelopeBuilder(which specify absolute physical frequencies in Hertz and amplitudes in Gs) don't have automatic fallback support. Because advanced PWLEs rely on specific hardware frequency curves (FOAM), substituting them automatically would compromise design intent. If the device doesn't support PWLE effects or the requested frequencies, such vibrations won't play. For universal compatibility, preferBasicEnvelopeBuilder.
Usage of VibrationEffect.Builder
For code examples on composing effects with VibrationEffect.Builder, see
Create timeline anchored compositions with
VibrationEffect.Builder.
VibrationEffect primitives composition
A VibrationEffect primitives composition is a vibration effect created
using the VibrationEffect.startComposition API. This API lets you create
a sequence of primitives.
Compatibility and requirements
Playing any VibrationEffect requires the VIBRATE permission in the app
manifest.
Check primitive support
Therefore, when using the VibrationEffect.Composition API, you must check
per-primitive support using Vibrator.arePrimitivesSupported or
Vibrator.areAllPrimitivesSupported before playing.
Per-primitive support can be retrieved using the
Vibrator.arePrimitivesSupported method. Alternatively, a set of primitives
may be checked together by using the Vibrator.areAllPrimitivesSupported
method - this is equivalent to AND-ing the per-primitive support.
Usage of VibrationEffect primitives compositions
For details on using VibrationEffect primitives compositions, see
Create vibration primitives compositions.
On-off, one-shot, and waveform vibrations
The oldest form of vibration supported on Android is simple vibrator on-off patterns with configurable durations. These APIs are typically not well aligned with Haptics design principles because they can generate buzzy haptics; avoid them except as a last resort.
The most common use case for on-off vibrations is notifications, where, no matter what, some vibration is desired. Waveform vibrations also uniquely allow a pattern to repeat indefinitely, as you might imagine for a ringtone.
A one-shot pattern refers to vibrating once for N milliseconds.
There are two types of waveform patterns:
- Timings-only. This type of waveform is a description of alternating durations spent off, and durations spent on. The timings start with the duration spent off. Consequently, waveform patterns often start with a zero value to indicate to immediately start vibrating.
- Timings and amplitudes. This type of waveform has an additional array of amplitudes to match with each timing figure, rather than the implicit on-off of the first form. However, it's important to check that the device supports amplitude control to ensure that the intended scaling can be achieved.
Compatibility and requirements
As on-off vibrations are the oldest form of vibrations, these are supported on virtually all devices with a vibrator, as described later on this page.
Playing any VibrationEffect or the older style vibrate calls, requires the
VIBRATE permission in the app manifest.
When using different amplitude values in a waveform, we strongly recommend that you that the device supports amplitude control.
Check for amplitude control support
Non-zero amplitude values are rounded up to 100% on devices without amplitude
control, so it is important to check if the support is present using
Vibrator.hasAmplitudeControl. See the amplitude control
for more details.
You should carefully consider whether your effect has sufficient quality without amplitude control. Falling back to an explicitly designed on-off vibration may be better.
Usage of on-off vibrations
In newer SDK levels, all vibration modes were consolidated into a single
expressive VibrationEffect class, where these simple vibrations are created
using VibrationEffect.createOneShot or VibrationEffect.createWaveform.
Notification APIs
When customizing your app notifications, you can use one of the following APIs to associate a pattern with each notification channel:
- AndroidX
- Android
All of these forms take a basic on-off waveform pattern, as described earlier, where the first entry is the delay before turning the vibrator on.
General concepts
Several concepts apply across the API surfaces detailed above.
Does the device have a vibrator?
You can obtain a non-null Vibrator class from
context.getSystemService(Vibrator.class). If the device doesn't have a
vibrator, calls to the vibration APIs don't have any effect, so apps don't need
to gate all of their haptics on a condition. However, if needed, an application
can call hasVibrator() to
determine if this is a real vibrator (true) or a stub (false).
Has the user disabled touch haptics?
Some custom implementations may require manually checking whether the user has
entirely disabled Android's Touch feedback
setting, in which case touch feedback effects should be suppressed. This setting
can be queried using the HAPTIC_FEEDBACK_ENABLED key, where a value of zero
means disabled.
Vibration attributes
Vibration attributes (currently in the form of AudioAttributes) can be
provided to help inform the system of the purpose of the vibration. This is
required when initiating a vibration when your app is in the background,
as only attentional haptics are supported for background usage.
The creation of AudioAttributes is covered in its class documentation, and
should be thought of as vibration rather than sound.
As a guide, in most cases, the content type is CONTENT_TYPE_SONIFICATION,
and the usage might be values such as USAGE_ASSISTANCE_SONIFICATION for
touch feedback in the foreground, or USAGE_ALARM for an alarm in the
background. Audio flags have no effect on vibrations.
Amplitude control
If a vibrator has amplitude control, then it can play vibrations with varying intensities. This is an important capability for producing rich haptics, as well as potentially allowing user control of default haptic intensities.
Amplitude control support can be checked by calling
Vibrator.hasAmplitudeControl. If a vibrator doesn't have amplitude
support, all amplitude values will map to off or on based on whether they are
zero or non-zero. Consequently, applications using rich haptics with varying
amplitudes should consider disabling them if the device lacks amplitude control.
Envelope effects support
Vibrators with envelope effects support and enable the creation of more dynamic
and nuanced vibrations, offering more precise control over intensity and
sharpness for richer haptic experiences. Use
Vibration.areEnvelopeEffectsSupported to determine if your device
supports this feature. If it doesn't, envelope based vibrations are ignored.