Mantenha tudo organizado com as coleções
Salve e categorize o conteúdo com base nas suas preferências.
Os atuadores de vibração mais comuns em dispositivos Android são atuadores lineares
ressonantes (LRAs, na sigla em inglês). Os LRAs simulam a sensação de um clique de botão
em uma superfície de vidro que não responde. Um sinal de feedback de clique
claro e nítido geralmente dura entre 10 e 20 milissegundos. Essa
sensação deixa as interações do usuário mais naturais. Para teclados virtuais, esse
feedback de clique pode aumentar a velocidade de digitação e reduzir erros.
Alguns LRAs tinham frequências de ressonância na faixa de 200 a 300 Hz, que
coincide com a frequência em que a pele humana é mais sensível à
vibração. A sensação de vibrações nessa faixa de frequência geralmente é
descrita como suave, nítida e penetrante.
Outros modelos de LRAs têm frequências de ressonância mais baixas, em torno de 150 Hz. A
sensação é qualitativamente mais suave e completa (em dimensão).
Componentes de um atuador de ressonância linear (LRA, na sigla em inglês).
Dada a mesma tensão de entrada em duas frequências diferentes, as amplitudes de saída da vibração
podem ser diferentes. Quanto mais distante a frequência estiver da frequência
ressonante do LRA, menor será a amplitude da vibração.
Os efeitos hápticos de um determinado dispositivo usam o atuador de vibração e o driver dele.
Drivers hápticos que incluem recursos de overdrive e frenagem ativa podem reduzir o
tempo de subida e o toque de LRAs, resultando em uma vibração mais responsiva e clara.
Aceleração da saída do vibrador
O mapeamento de frequência-aceleração-de-saída (FOAM, na sigla em inglês) descreve a aceleração de saída
máxima (em G pico) em uma determinada frequência de vibração (em
hertz). A partir do Android 16 (nível 36 da API), a plataforma oferece suporte integrado
a esse mapeamento pelo VibratorFrequencyProfile. É possível usar
essa classe, junto com as APIs de envelope básico e avançado, para criar
efeitos hápticos.
A maioria dos motores de LRA tem um único pico na FOAM, normalmente próximo à frequência
ressonante. A aceleração geralmente diminui exponencialmente à medida que a frequência se desvia
deste intervalo. A curva pode não ser simétrica e pode apresentar um platô
em torno da frequência de ressonância para proteger o motor contra danos.
O gráfico adjacente mostra um exemplo de FOAM para um motor de LRA.
Exemplo de FOAM para um motor de LRA.
Limite de detecção de percepção humana
O limite de detecção da percepção humana se refere à aceleração mínima de
uma vibração que uma pessoa pode detectar com confiabilidade. Esse nível varia de acordo com a
frequência da vibração.
O gráfico adjacente mostra o limiar de detecção de percepção tátil humana, em
aceleração, como uma função da frequência temporal. Os dados de limite são
convertidos do limite de deslocamento na Figura 1 de Bolanowski Jr., S. J., et
al.'s 1988 article,
"Four channels mediate the mechanical aspects of touch.".
O Android processa automaticamente esse limite no BasicEnvelopeBuilder,
que verifica se todos os efeitos usam um intervalo de frequência que produz amplitudes
de vibração que excedam o limite de detecção de percepção humana em pelo menos
10 dB.
A percepção humana da intensidade da vibração, uma medida de percepção, não aumenta
linearmente com a amplitude da vibração, um parâmetro físico. A intensidade percebida
é caracterizada pelo nível de sensação (SL, na sigla em inglês), que é definido como uma quantidade de dB acima
do limite de detecção na mesma frequência.
A amplitude de aceleração de vibração correspondente (em G de pico) pode ser calculada
da seguinte maneira:
$$
Amplitude(G) = 10^{Amplitude(db)/20}
$$
...em que o dB de amplitude é a soma do SL e do limite de detecção, ou seja, o valor
ao longo do eixo vertical no gráfico adjacente, em uma frequência específica.
O gráfico adjacente mostra os níveis de aceleração da vibração em 10, 20, 30, 40 e
50 dB SL, junto com o limiar de detecção de percepção tátil humana (0 dB SL),
como uma função da frequência temporal. Os dados são estimados com base na Figura 8 em
Verrillo, R. T., et al.'s 1969 article, "Sensation magnitude of vibrotactile
stimuli.".
Níveis de aceleração da vibração.
O Android processa essa conversão automaticamente no BasicEnvelopeBuilder,
que recebe valores como intensidades normalizadas no espaço do nível de sensação (dB
SL) e os converte em aceleração de saída. O WaveformEnvelopeBuilder, por
outro lado, não aplica essa conversão e recebe valores como amplitudes de aceleração de saída
normalizadas no espaço de aceleração (Gs). A
API de envelope pressupõe que, quando um designer ou desenvolvedor pensa em mudanças na
intensidade da vibração, ele espera que a intensidade percebida siga um envelope
linear por partes.
Suavização de forma de onda padrão em dispositivos
Para ilustrar, considere como um padrão de forma de onda personalizada se comporta em um dispositivo
genérico:
Os gráficos a seguir mostram a forma de onda de entrada e a aceleração de saída
correspondentes aos snippets de código anteriores. A aceleração
aumenta gradualmente, não de repente, sempre que há uma mudança de amplitude
no padrão, ou seja, em 0 ms, 150 ms, 200 ms, 250 ms e 700 ms. Há também um
overshoot em cada mudança de etapa de amplitude, e há um som de campainha visível que
dura pelo menos 50 ms quando a amplitude de entrada cai repentinamente para 0.
Gráfico da forma de onda de entrada da função escalonada.
Gráfico da forma de onda medida real, mostrando transições mais orgânicas
entre os níveis.
Padrão tátil aprimorado
Para evitar o excesso e reduzir o tempo de toque, mude as amplitudes de forma mais
gradual. A seguir, são mostrados os gráficos de forma de onda e aceleração da
versão revisada:
Kotlin
valtimings:LongArray=longArrayOf(25,25,50,25,25,25,25,25,25,25,75,25,25,300,25,25,150,25,25,25)valamplitudes:IntArray=intArrayOf(38,77,79,84,92,99,121,143,180,217,255,170,85,0,85,170,255,170,85,0)valrepeatIndex=-1// Do not repeat.vibrator.vibrate(VibrationEffect.createWaveform(timings,amplitudes,repeatIndex))
Java
long[]timings=newlong[]{25,25,50,25,25,25,25,25,25,25,75,25,25,300,25,25,150,25,25,25};int[]amplitudes=newint[]{38,77,79,84,92,99,121,143,180,217,255,170,85,0,85,170,255,170,85,0};intrepeatIndex=-1;// Do not repeat.vibrator.vibrate(VibrationEffect.createWaveform(timings,amplitudes,repeatIndex));
Gráfico da forma de onda de entrada com etapas adicionais.
Gráfico da forma de onda medida, mostrando transições mais suaves.
Criar efeitos táteis mais complexos
Outros elementos em uma resposta satisfatória de clique são mais complicados, exigindo algum
conhecimento do LRA usado em um dispositivo. Para melhores resultados, use as formas de onda
pré-fabricadas do dispositivo e as constantes fornecidas pela plataforma, que permitem fazer o
seguinte:
Faça a concatenação para criar novos efeitos hápticos.
Essas constantes e primitivas pré-definidas podem acelerar muito seu trabalho
ao criar efeitos hápticos de alta qualidade.
O conteúdo e os exemplos de código nesta página estão sujeitos às licenças descritas na Licença de conteúdo. Java e OpenJDK são marcas registradas da Oracle e/ou suas afiliadas.
Última atualização 2025-07-27 UTC.
[null,null,["Última atualização 2025-07-27 UTC."],[],[],null,["# Analyze vibration waveforms\n\nThe most common vibration actuators on Android devices are [linear resonant\nactuators (LRAs)](https://medium.com/@SomaticLabs/what-is-a-linear-resonant-actuator-81cc25f85779). LRAs simulate the feeling of a button click\non what is otherwise an unresponsive glass surface. A clear and crisp click\nfeedback signal typically lasts between 10 and 20 milliseconds in duration. This\nsensation makes user interactions feel more natural. For virtual keyboards, this\nclick feedback can increase typing speed and reduce errors.\n\nLRAs have a few common [resonant frequencies](https://en.wikipedia.org/wiki/Resonance#Examples):\n\n- Some LRAs had resonant frequencies in the 200 to 300 Hz range, which coincides with the frequency at which human skin is most sensitive to vibration. The sensation of vibrations at this frequency range are usually described as smooth, sharp, and penetrating.\n- Other models of LRAs have lower resonance frequencies, at around 150 Hz. The sensation is qualitatively softer and fuller (in dimension). \nComponents of a linear resonant actuator (LRA).\n\n\u003cbr /\u003e\n\nGiven the same input voltage at two different frequencies, the vibration output\namplitudes can be different. The further away the frequency is from the LRA's\nresonant frequency, the lower its vibration amplitude.\n\nA given device's haptic effects use both the vibration actuator and its driver.\nHaptic drivers that include overdrive and active braking features can reduce the\nrise time and ringing of LRAs, leading to a more responsive and clear vibration.\n\nVibrator output acceleration\n----------------------------\n\n\nThe frequency-to-output-acceleration mapping (FOAM) describes the maximum\nachievable output acceleration (in G peak) at a given vibration frequency (in\nHertz). Starting in Android 16 (API level 36), the platform provides built-in\nsupport for this mapping through the `VibratorFrequencyProfile`. You can use\nthis class, along with the [basic](/reference/android/os/VibrationEffect.BasicEnvelopeBuilder) and [advanced](/reference/android/os/VibrationEffect.WaveformEnvelopeBuilder) envelope APIs, to create\nhaptic effects.\n\nMost LRA motors have a single peak in their FOAM, typically near their resonant\nfrequency. Acceleration generally decreases exponentially as frequency deviates\nfrom this range. The curve may not be symmetrical and might feature a plateau\naround the resonant frequency to protect the motor from damage.\n\nThe adjacent plot shows an example FOAM for an LRA motor. \nExample FOAM for an LRA motor.\n\n\u003cbr /\u003e\n\n### Human perception detection threshold\n\n\nThe *human perception detection threshold* refers to the minimum acceleration of\na vibration that a person can reliably detect. This level varies based on the\nvibration frequency.\n\nThe adjacent plot shows the human haptic perception detection threshold, in\nacceleration, as a function of temporal frequency. The threshold data is\nconverted from displacement threshold in Figure 1 of Bolanowski Jr., S. J., et\nal.'s 1988 article,\n[\"Four channels mediate the mechanical aspects of touch.\"](https://pubmed.ncbi.nlm.nih.gov/3209773/).\n\nAndroid automatically handles this threshold in the `BasicEnvelopeBuilder`,\nwhich verifies that all effects use a frequency range that prodcues vibration\namplitudes that exceed the human perception detection threshold by at least\n10 dB. \nHuman haptic perception detection threshold.\n\n\u003cbr /\u003e\n\nAn online tutorial further explains the [conversion between acceleration\namplitude and displacement amplitude](https://www.tangerinex.com/tutorial-1).\n\n### Vibration acceleration levels\n\n\nHuman perception of vibration intensity, a *perception* measure, doesn't grow\nlinearly with vibration amplitude, a *physical* parameter. Perceived intensity\nis characterized by sensation level (SL), which is defined as a dB amount above\nthe detection threshold at the same frequency.\n\nThe corresponding vibration acceleration amplitude (in G peak) can be calculated\nas follows: \n$$ Amplitude(G) = 10\\^{Amplitude(db)/20} $$\n\n...where the amplitude dB is the sum of SL and detection threshold---the value\nalong the vertical axis in the adjacent plot---at a particular frequency.\n\nThe adjacent plot shows the vibration acceleration levels at 10, 20, 30, 40 and\n50 dB SL, along with the human haptic perception detection threshold (0 dB SL),\nas a function of temporal frequency. The data is estimated from Figure 8 in\nVerrillo, R. T., et al.'s 1969 article, [\"Sensation magnitude of vibrotactile\nstimuli.\"](https://link.springer.com/article/10.3758/BF03212793). \nVibration acceleration levels.\n\n\u003cbr /\u003e\n\nAndroid automatically handles this conversion in the `BasicEnvelopeBuilder`,\nwhich takes values as normalized intensities in the sensation level space (dB\nSL) and converts them to output acceleration. The `WaveformEnvelopeBuilder`, on\nthe other hand, doesn't apply this conversion and takes values as normalized\noutput acceleration amplitudes in the acceleration space (Gs) instead. The\nenvelope API assumes that, when a designer or developer thinks about changes in\nvibration strength, they expect the perceived intensity to follow a piecewise\nlinear envelope.\n\nDefault waveform smoothing on devices\n-------------------------------------\n\nFor illustration, consider how a custom waveform pattern behaves on a generic\ndevice: \n\n### Kotlin\n\n val timings: LongArray = longArrayOf(50, 50, 50, 50, 50, 100, 350, 250)\n val amplitudes: IntArray = intArrayOf(77, 79, 84, 99, 143, 255, 0, 255)\n val repeatIndex = -1 // Don't repeat.\n\n vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex))\n\n### Java\n\n long[] timings = new long[] { 50, 50, 50, 50, 50, 100, 350, 250 };\n int[] amplitudes = new int[] { 77, 79, 84, 99, 143, 255, 0, 255 };\n int repeatIndex = -1 // Don't repeat.\n\n vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex));\n\nThe following plots show the input waveform and output acceleration\ncorresponding to the preceding code snippets. Note that the acceleration\nincreases gradually, not suddenly, whenever there is a step change of amplitude\nin the pattern---that is, at 0ms, 150ms, 200ms, 250ms, and 700ms. There is also an\novershoot at each step change of amplitude, and there is visible ringing that\nlasts at least 50ms when the input amplitude suddenly drops to 0.\n\n\nPlot of step function input waveform. \nPlot of actual measured waveform, showing more organic transitions between levels.\n\n\u003cbr /\u003e\n\nImproved haptic pattern\n-----------------------\n\nTo avoid overshoot and reduce ringing time, change the amplitudes more\ngradually. The following shows the waveform and acceleration plots of the\nrevised version: \n\n### Kotlin\n\n val timings: LongArray = longArrayOf(\n 25, 25, 50, 25, 25, 25, 25, 25, 25, 25, 75, 25, 25,\n 300, 25, 25, 150, 25, 25, 25\n )\n val amplitudes: IntArray = intArrayOf(\n 38, 77, 79, 84, 92, 99, 121, 143, 180, 217, 255, 170, 85,\n 0, 85, 170, 255, 170, 85, 0\n )\n val repeatIndex = -1 // Do not repeat.\n\n vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex))\n\n### Java\n\n long[] timings = new long[] {\n 25, 25, 50, 25, 25, 25, 25, 25, 25, 25, 75, 25, 25,\n 300, 25, 25, 150, 25, 25, 25\n };\n int[] amplitudes = new int[] {\n 38, 77, 79, 84, 92, 99, 121, 143, 180, 217, 255, 170, 85,\n 0, 85, 170, 255, 170, 85, 0\n };\n int repeatIndex = -1; // Do not repeat.\n\n vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex));\n\n\nPlot of input waveform with additional steps. \nPlot of measured waveform, showing smoother transitions.\n\n\u003cbr /\u003e\n\nCreate more complex haptic effects\n----------------------------------\n\nOther elements in a satisfying click response are more intricate, requiring some\nknowledge of the LRA used in a device. For best results, use the device's\npre-fabricated waveforms and platform-provided constants, which let you do the\nfollowing:\n\n- Perform clear effects and [primitives](/develop/ui/views/haptics/custom-haptic-effects#primitives).\n- Concatenate them to compose new haptic effects.\n\nThese predefined haptic constants and primitives can greatly speed up your work\nwhile creating high-quality haptic effects."]]