Added in [API level 37.2](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)

# Builder

*** ** * ** ***

```
class Builder
```

|---|---|
| [kotlin.Any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-any/index.html) ||
| ↳ | [android.os.VibrationEffect.Builder](https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#) |

A builder for composing haptic effects by sequencing various haptic elements.

This API is the preferred alternative to `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Composition` for creating complex vibration effects. It offers more flexibility for creating haptic patterns by allowing multiple elements to be scheduled at specific points in a timeline.

This builder allows you to add `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Envelope`s, `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Preset`s, and existing `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`s (as `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Event`s) to create a complex waveform. Each element is added with a specified `startTimeMillis`. Note that the use of legacy `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`s is not recommended here.

Additionally, a repeating part can be set using `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#setRepeatingEffect(kotlin.Long,%20android.os.VibrationEffect,%20kotlin.Long)`. Once a repeating effect is set, no more haptic elements can be added to the composition.

**Fallback Support:** Vibrations created by this builder will provide fallback support if the device does not support the requested haptic elements.

Note that fallback support is **not** provided for envelope effects created by `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.WaveformEnvelopeBuilder`, even when they are added to this builder. For such effects, if the device does not support PWLE effects or the requested frequencies, the vibration will not play.

For more details about the background of haptics implementation and how OEMs support these effects, see the [Android Haptics Implementation Guidelines](https://source.android.com/docs/core/interaction/haptics/haptics-implement).

**Timing and Alignment:** The `startTimeMillis` is the time in milliseconds from the start of the composition being built. Elements must be added in increasing order of their start times.

The framework provides **best-effort timing support** during playback. If a previous event is still playing back when the next event's specified start time is reached, the framework will automatically shift the next event to the next earliest slot. This guarantees that no haptic feedback is dropped and events do not overlap in the actual playback (they will play sequentially instead).

However, this automatic shifting can introduce timing drift. To ensure that the actual playback timing aligns as closely as possible with your specified timeline, the builder performs **best-effort validation** at build time to help you avoid scheduling elements too close together. This validation uses known durations of some elements (like `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Envelope`s) or a minimum duration (1ms) for device-dependent elements (like `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Preset`s). If a potential overlap is detected at build time, an `https://developer.android.com/reference/kotlin/java/lang/IllegalArgumentException.html#` is thrown.

Because the actual duration of some elements is only fully known at runtime on the physical device, developers should still be mindful when sequencing elements with variable durations to ensure the best alignment between the designed and actual playback timing.

## Summary

| Public constructors ||
|---|---|
| `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#Builder()()` Creates an empty `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` to compose a new `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`. |
| `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#Builder(android.os.VibrationEffect)(effect: https://developer.android.com/reference/kotlin/android/os/VibrationEffect)` Creates a `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` initialized with a copy of an existing `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`. |

| Public methods ||
|---|---|
| [VibrationEffect.Builder](https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#) | `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#addEnvelope(kotlin.Long,%20android.os.VibrationEffect.Envelope)(startTimeMillis: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html, envelope: https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Envelope)` Adds a haptic `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Envelope` to the composition. |
| [VibrationEffect.Builder](https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#) | `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#addEvents(kotlin.Long,%20kotlin.collections.MutableList)(startTimeShiftMillis: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html, events: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/index.html<https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Event!>)` Adds a list of existing `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Event`s to the composition. |
| [VibrationEffect.Builder](https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#) | `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#addPreset(kotlin.Long,%20android.os.VibrationEffect.Preset)(startTimeMillis: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html, preset: https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Preset)` Adds a predefined haptic `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Preset` to the composition. |
| [VibrationEffect](https://developer.android.com/reference/kotlin/android/os/VibrationEffect) | `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#build()()` Builds the composed `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`. |
| [VibrationEffect.Builder](https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#) | `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#setRepeatingEffect(kotlin.Long,%20android.os.VibrationEffect,%20kotlin.Long)(startTimeMillis: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html, effect: https://developer.android.com/reference/kotlin/android/os/VibrationEffect, durationMillis: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html)` Adds a repeating haptic effect to the composition. |

## Public constructors

### Builder

Added in [API level 37.2](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)

```
Builder()
```

Creates an empty `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` to compose a new `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`.

### Builder

Added in [API level 37.2](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)

```
Builder(effect: VibrationEffect)
```

Creates a `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` initialized with a copy of an existing `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`.

Initializes the builder by copying the sequence of events from the provided `effect`.

| Parameters ||
|---|---|
| `effect` | [VibrationEffect](https://developer.android.com/reference/kotlin/android/os/VibrationEffect): The `https://developer.android.com/reference/kotlin/android/os/VibrationEffect` to initialize this builder with. This value cannot be `null`. |

| Exceptions ||
|---|---|
| `java.lang.IllegalStateException` | if the `effect` is repeating. |
| `java.lang.NullPointerException` | if the provided `effect` is null. |

## Public methods

### addEnvelope

Added in [API level 37.2](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)

```
fun addEnvelope(
    startTimeMillis: Long, 
    envelope: VibrationEffect.Envelope
): VibrationEffect.Builder
```

Adds a haptic `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Envelope` to the composition.

The `startTimeMillis` is the time in milliseconds from the start of the composition being built. The envelope will be scheduled to start at this time.

The builder performs best-effort validation to prevent overlaps with previously added elements. The duration of an `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Envelope` is generally well-defined, but care should still be taken with the `startTimeMillis` to ensure correct sequencing with other elements.

**Fallback Support:** If the envelope is created using `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.WaveformEnvelopeBuilder`, fallback support is **not** provided. If the device does not support the envelope, the entire vibration effect may fail to play. Envelopes created using `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.BasicEnvelopeBuilder` will have fallback support.

| Parameters ||
|---|---|
| `startTimeMillis` | [Long](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html): The time in milliseconds from the start of the composition to start the envelope. Value is a non-negative duration in milliseconds. |
| `envelope` | [VibrationEffect.Envelope](https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Envelope): The `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Envelope` to add. This value cannot be `null`. |

| Return ||
|---|---|
| `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` | This `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` object. This value cannot be `null`. |

| Exceptions ||
|---|---|
| `java.lang.IllegalArgumentException` | if adding the envelope would result in overlapping haptic elements. |
| `java.lang.NullPointerException` | if the provided `envelope` is null. |

### addEvents

Added in [API level 37.2](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)

```
fun addEvents(
    startTimeShiftMillis: Long, 
    events: MutableList<VibrationEffect.Event!>
): VibrationEffect.Builder
```

Adds a list of existing `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Event`s to the composition.

Each event in the list has a start time relative to the start of the composition it was retrieved from. The `startTimeShiftMillis` parameter is added to the start time of each event in the list, effectively shifting the whole block of events forward or backward in the timeline of this builder.

For example, if an event within the list has a start time of 50ms, and `startTimeShiftMillis` is 100ms, the event will be shifted to start at 150ms within this builder's timeline.

All events will be added and validated according to the builder's timing rules, with best-effort checks to prevent overlaps being introduced by the shift.

You can get events by calling `https://developer.android.com/reference/kotlin/android/os/VibrationEffect#getEvents()` on non-repeating effects.

| Parameters ||
|---|---|
| `startTimeShiftMillis` | [Long](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html): The non-negative time in milliseconds to add to the start time of each event in the provided list. Value is a non-negative duration in milliseconds. |
| `events` | [MutableList](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/index.html)\<[VibrationEffect.Event](https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Event)!\>: The list of events to add. This value cannot be `null`. |

| Return ||
|---|---|
| `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` | This `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` object. This value cannot be `null`. |

| Exceptions ||
|---|---|
| `java.lang.IllegalArgumentException` | if `startTimeShiftMillis` is negative or if adding any of the events would result in overlapping haptic elements. |
| `java.lang.NullPointerException` | if the provided `events` list is null. |

### addPreset

Added in [API level 37.2](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)

```
fun addPreset(
    startTimeMillis: Long, 
    preset: VibrationEffect.Preset
): VibrationEffect.Builder
```

Adds a predefined haptic `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Preset` to the composition.

The `startTimeMillis` is the time in milliseconds from the start of the composition being built. The preset will be scheduled to start at this time.

The builder performs best-effort validation to prevent overlaps with previously added elements. However, the exact duration of a `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Preset` can be device-dependent. It is the caller's responsibility to choose an appropriate `startTimeMillis` to avoid unintended overlaps.

| Parameters ||
|---|---|
| `startTimeMillis` | [Long](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html): The time in milliseconds from the start of the composition to start the preset. Value is a non-negative duration in milliseconds. |
| `preset` | [VibrationEffect.Preset](https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Preset): The `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Preset` to add. This value cannot be `null`. |

| Return ||
|---|---|
| `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` | This `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` object. This value cannot be `null`. |

| Exceptions ||
|---|---|
| `java.lang.IllegalArgumentException` | if adding the preset would result in overlapping haptic elements. |
| `java.lang.NullPointerException` | if the provided `preset` is null. |

### build

Added in [API level 37.2](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)

```
fun build(): VibrationEffect
```

Builds the composed `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`.

This method finalizes the composition of all added elements (Envelopes, Presets, Events) and returns a single `https://developer.android.com/reference/kotlin/android/os/VibrationEffect` that can be played by the vibrator.

The `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` object is still valid after this call, so you can continue adding more elements to it and generate more `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`s by calling this method again.

Automatic fallback will be supported for the built `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`. If the device does not support some of the composed haptic elements, they will be automatically mapped to fallback effects at runtime (except for elements that explicitly do not support fallback, such as envelopes from `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.WaveformEnvelopeBuilder`).

| Return ||
|---|---|
| `https://developer.android.com/reference/kotlin/android/os/VibrationEffect` | The resulting `https://developer.android.com/reference/kotlin/android/os/VibrationEffect`. This value cannot be `null`. |

| Exceptions ||
|---|---|
| `java.lang.IllegalArgumentException` | if the validation of the composed effect fails (e.g., due to timing issues, invalid haptic element parameters). |
| `java.lang.IllegalStateException` | if the composition is empty. |

### setRepeatingEffect

Added in [API level 37.2](https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels)

```
fun setRepeatingEffect(
    startTimeMillis: Long, 
    effect: VibrationEffect, 
    durationMillis: Long
): VibrationEffect.Builder
```

Adds a repeating haptic effect to the composition.

The `startTimeMillis` is the time in milliseconds from the start of the composition being built. The repeating effect will be scheduled to start at this time.

The `durationMillis` specifies the total length of one repeat cycle. If the provided `effect` has a shorter natural duration (the time from the start of the first segment to the end of the last segment), a pause (silence) will be added at the end of each cycle to fill the remaining time. For example, if the `effect` lasts 150ms and `durationMillis` is 1000ms, then the effect will play once and be followed by an 850ms pause before repeating again.

After this method is called, no more haptic elements can be added to the composition.

| Parameters ||
|---|---|
| `startTimeMillis` | [Long](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html): The non-negative time in milliseconds from the start of the composition to start the repeating effect. Value is a non-negative duration in milliseconds. |
| `effect` | [VibrationEffect](https://developer.android.com/reference/kotlin/android/os/VibrationEffect): The non-repeating `https://developer.android.com/reference/kotlin/android/os/VibrationEffect` to be repeated. This value cannot be `null`. |
| `durationMillis` | [Long](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-long/index.html): The positive total duration of each repeat cycle, including any trailing pause. Must be greater than or equal to the duration of the effect if the duration is known; otherwise, a best-effort check based on the estimated duration is performed to prevent impossible values. Value is 1 or greater. Value is a non-negative duration in milliseconds. |

| Return ||
|---|---|
| `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` | This `https://developer.android.com/reference/kotlin/android/os/VibrationEffect.Builder#` object. This value cannot be `null`. |

| Exceptions ||
|---|---|
| `java.lang.IllegalArgumentException` | if the provided effect is already repeating, if `startTimeMillis` is negative, or if `durationMillis` is not positive. |
| `java.lang.IllegalStateException` | if a repeating effect has already been set, or if other elements are added after this call. |
| `java.lang.NullPointerException` | if the provided `effect` is null. |