Google is committed to advancing racial equity for Black communities. See how.

UX Foundation for Haptic Framework

All Android framework improvements built around haptics are driven by a set of UX principles that are evolving at an equal rate. The current principles involve replacing buzzy vibration with clear haptics, and exploring rich haptics.

UX Principles

Figure 1. Current principles

APIs by Year

Figure 2. Haptics APIs by year

Buzzy vibration

Dating back to pagers and feature phones, low-quality but power-efficient ERM buzzer-based vibrations have been used as a substitute for auditory ringing in silent mode. The legacy hardware components that produce loud and unpleasant audible noises can harm haptic UX by delivering low-quality impressions (for example, a cheap, broken phone).

Clear haptics

Clear haptics support the sensation of discrete state changes (for example, binary changes during the power on/off process). Due to the nature of the discrete affordance, clear haptics are generated as a single entity (for example, one haptic effect per one input event).

Android aims to deliver clear haptics with strong, yet sharp sensations rather than sensations that are buzzy or mushy.

Predefined haptic constants that are created to support clear haptics include the following.

In HapticFeedbackConstants:

  • CLOCK_TICK
  • CONFIRM
  • CONTEXT_CLICK
  • GESTURE_END
  • GESTURE_START
  • KEYBOARD_PRESS
  • KEYBOARD_RELEASE
  • KEYBOARD_TAP
  • LONG_PRESS
  • REJECT
  • TEXT_HANDLE_MOVE
  • VIRTUAL_KEY
  • VIRTUAL_KEY_RELEASE

In VibrationEffect:

  • EFFECT_CLICK
  • EFFECT_DOUBLE_CLICK
  • EFFECT_HEAVY_CLICK
  • EFFECT_TICK

Building common knowledge between device manufacturers and developers is key to raising the overall quality of haptics in the Android ecosystem. Use the basic checklist, hardware assessment, and CDD. to learn more about haptic implementation.

Press and Release

Figure 3. Pressing and releasing.

Rich haptics

Rich haptics is a growing haptics category that goes beyond single impulse-based effects. Android aims to support rich haptics with high composability and adjustability with a fine level of granularity. The following use cases are supported in Android 11 or lower.

Rich Haptics

Figure 4. Rich haptics with sliding texture

Dragging and Swiping

Figure 5. Dragging and swiping

Use case 1: Sliding texture

If a haptic effect is repeated while the finger slides over a touch surface (for example, dragging, swiping, exploring the surface with phantom haptic texture), the repeating haptic effects are preferably crisp and subtle.

If the individual effect is buzzy rather than crisp, then the intervals between the repetitions are likely to be wiped out. The outcome is one long buzz, rather than multiple discrete signals.

If the amplitude isn't subtle enough, then the perceived haptic energy builds up through the repetition, resulting in overwhelmingly strong haptics at the end of the repetition.

Implementing a simple surface haptic texture for swipe and drag gestures

Use CLOCK_TICK and TEXT_HANDLE_MOVE in HapticFeedbackConstants. These constants predefine characteristics of repetition and amplitude.

Creating your own effect

To make your own effect, compose a design by stringing together sequences of PRIMITIVE_CLICK and PRIMITIVE_TICK in VibrationEffect.Composition. You can adjust the characteristics of the repetition and amplitude scale using addPrimitive(int primitiveID, float scale, int delay). Support relies on the CAP_COMPOSE_EFFECTS capability of the Vibrator HAL Interface.

Use case 2: Long vibration with ease-in effect

Long vibration is a smooth amplitude vibration that transitions from 0 to the target amplitude. Long vibration can generate easily perceivable attentional haptics. However, a sudden long vibration can startle users in a quiet environment, and often produces audible buzzing noises. To generate a more pleasant long vibration, apply the ease-in effect at the beginning of the long vibration. This produces a smooth amplitude transition that builds toward the target amplitude.

Applying the ease-in effect

  1. Check hardware capabilities of amplitude control with android.os.Vibrator.hasAmplitudeControl().

    • The result has to be true to produce ease-in effect with varying amplitude.
  2. Use VibrationEffect.createWaveform(timings[], amplitudes[], int repeat).

  3. Adjust the series of timings[] and amplitudes[] to generate the ease-in curve, as shown in Figure 6.

Long Vibration

Figure 6. Long vibration ease-in curve

Use case 3: Audio-coupled haptics

Audio-coupled haptics are haptic patterns coupled with the rhythm of the audio to get the user's attention.

Audio-coupled haptics: Benefits

To implement audio-coupled haptics, combine clear haptics with long vibrations. The strong but short haptic sensations from clear haptics deliver discrete rhythmic patterns. When combined with the high levels of stimuli that long vibration provides, this does a great job of getting a user's attention.

It's important to consider the sensation rhythmic patterns. If there's no sense of rhythm, the user perceives the haptic sensations as random buzzes, and tends to ignore them.

Audio Couple

Figure 7. Audio couple haptics example

Audio-coupled haptics: Tips for implementing

Implementing audio-coupled haptics requires a basic understanding of content playback of both audio and haptic channels. Keep the following things in mind.

  • Use the MediaPlayer or SoundPool classes.

    • Assets in OGG format with a special metadata key (ANDROID_HAPTIC followed by a number of haptic channels) indicate the presence of haptics data and playback with MediaPlayer and SoundPool.
  • Indicate support of haptics and audio playback in audio_policy_configuration.xml.

    • Use an output profile with haptics channel AUDIO_CHANNEL_OUT_HAPTIC_A|B.
    • For an output stream with haptic channels, remember that haptic channels are presented as extra channels in the data.

    Example

    If the channel mask for the output stream looks like this:

    AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A

    Then every sample should look like this:

    AUDIO_LEFT_CHANNEL,AUDIO_RIGHT_CHANNEL,HAPTIC_CHANNEL_A

  • Change AudioAttributes.Builder( ).setHapticChannelsMuted(boolean muted)

    to false to play the haptic channel.

    • By default, haptic channels are muted (true).
    • Use cases include ringtones and UI sounds with synchronous haptics and feedback.
  • The Vibrator HAL must implement external control support.

Audio Coupled Haptics

Figure 8. Implementing audio-coupled haptics