Organiza tus páginas con colecciones
Guarda y categoriza el contenido según tus preferencias.
Los actuadores de vibración más comunes en los dispositivos Android son los actuadores resonantes lineales (LRAs). Los LRA simulan la sensación de hacer clic en un botón en una superficie de vidrio que, de otro modo, no respondería. Una señal de respuesta de clic clara y nítida suele durar entre 10 y 20 milisegundos. Esta sensación hace que las interacciones del usuario se sientan más naturales. En el caso de los teclados virtuales, estos comentarios de clic pueden aumentar la velocidad de escritura y reducir los errores.
Algunos LRA tenían frecuencias resonantes en el rango de 200 a 300 Hz, que coincide con la frecuencia a la que la piel humana es más sensible a la vibración. La sensación de vibraciones en este rango de frecuencia suele describirse como suave, nítida y penetrante.
Otros modelos de LRA tienen frecuencias de resonancia más bajas, alrededor de 150 Hz. La sensación es cualitativamente más suave y completa (en dimensión).
Componentes de un actuador resonante lineal (LRA).
Dado el mismo voltaje de entrada en dos frecuencias diferentes, las amplitudes de salida de vibración pueden ser diferentes. Cuanto más alejada esté la frecuencia de la frecuencia resonante del LRA, menor será su amplitud de vibración.
Los efectos táctiles de un dispositivo determinado usan el actuador de vibración y su controlador.
Los controladores táctiles que incluyen funciones de sobremarcha y frenado activo pueden reducir el tiempo de aumento y el timbre de los LRA, lo que genera una vibración más responsiva y clara.
Aceleración de salida del vibrador
La asignación de frecuencia a aceleración de salida (FOAM) describe la aceleración de salida máxima alcanzable (en G pico) a una frecuencia de vibración determinada (en hercios). A partir de Android 16 (nivel de API 36), la plataforma proporciona compatibilidad integrada con esta asignación a través de VibratorFrequencyProfile. Puedes usar esta clase, junto con las APIs de sobres básicos y avanzados, para crear efectos táctiles.
La mayoría de los motores de LRA tienen un solo pico en su FOAM, por lo general, cerca de su frecuencia resonante. La aceleración generalmente disminuye de forma exponencial a medida que la frecuencia se desvía
de este rango. Es posible que la curva no sea simétrica y tenga una meseta alrededor de la frecuencia resonante para proteger el motor del daño.
En el gráfico adyacente, se muestra un ejemplo de FOAM para un motor de LRA.
Ejemplo de FOAM para un motor de LRA.
Umbral de detección de percepción humana
El umbral de detección de percepción humana hace referencia a la aceleración mínima de una vibración que una persona puede detectar de forma confiable. Este nivel varía según la frecuencia de vibración.
El gráfico adyacente muestra el umbral de detección de la percepción táctil humana, en
aceleración, como una función de la frecuencia temporal. Los datos del umbral se convierten del umbral de desplazamiento en la Figura 1 de Bolanowski Jr., S. J., et al., 1988, “Four channels mediate the mechanical aspects of touch”.
Android controla automáticamente este umbral en BasicEnvelopeBuilder, que verifica que todos los efectos usen un rango de frecuencia que produzca amplitudes de vibración que superen el umbral de detección de percepción humana en al menos 10 dB.
Umbral de detección de la percepción táctil humana.
La percepción humana de la intensidad de la vibración, una medida de percepción, no crece de forma lineal con la amplitud de la vibración, un parámetro físico. La intensidad percibida se caracteriza por el nivel de sensación (SL), que se define como una cantidad de dB por encima del umbral de detección en la misma frecuencia.
La amplitud de aceleración de vibración correspondiente (en G pico) se puede calcular de la siguiente manera:
$$
Amplitude(G) = 10^{Amplitude(db)/20}
$$
…en la que la amplitud en dB es la suma de la SL y el umbral de detección (el valor a lo largo del eje vertical en el gráfico adyacente) en una frecuencia en particular.
En el gráfico adyacente, se muestran los niveles de aceleración de vibración a 10, 20, 30, 40 y 50 dB SL, junto con el umbral de detección de percepción táctil humana (0 dB SL), como función de la frecuencia temporal. Los datos se estiman a partir de la figura 8 en Verrillo, R. T., et al., "Sensation magnitude of vibrotactile stimuli", artículo de 1969.
Niveles de aceleración de la vibración.
Android controla automáticamente esta conversión en BasicEnvelopeBuilder, que toma valores como intensidades normalizadas en el espacio de nivel de sensación (dB SL) y los convierte en aceleración de salida. Por otro lado, WaveformEnvelopeBuilder no aplica esta conversión y, en su lugar, toma valores como amplitudes de aceleración de salida normalizadas en el espacio de aceleración (G). La API de envelope supone que, cuando un diseñador o desarrollador piensa en cambios en la intensidad de la vibración, espera que la intensidad percibida siga una envolvente lineal por partes.
Suavización predeterminada de la forma de onda en los dispositivos
A modo de ejemplo, considera cómo se comporta un patrón de forma de onda personalizado en un dispositivo genérico:
En los siguientes gráficos, se muestran la forma de onda de entrada y la aceleración de salida que corresponden a los fragmentos de código anteriores. Ten en cuenta que la aceleración aumenta gradualmente, no de forma repentina, cada vez que hay un cambio brusco de amplitud en el patrón, es decir, a los 0 ms, 150 ms, 200 ms, 250 ms y 700 ms. También hay un exceso en cada cambio de paso de amplitud, y hay un timbre visible que dura al menos 50 ms cuando la amplitud de entrada cae repentinamente a 0.
Gráfico de la forma de onda de entrada de la función de paso.
Gráfico de la forma de onda medida real, que muestra transiciones más orgánicas entre los niveles.
Patrón táctil mejorado
Para evitar el sobreimpulso y reducir el tiempo de timbre, cambia las amplitudes de forma más gradual. A continuación, se muestran las formas de onda y los gráficos de aceleración de la versión 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 de la forma de onda de entrada con pasos adicionales.
Gráfico de la forma de onda medida, que muestra transiciones más suaves.
Crea efectos táctiles más complejos
Otros elementos de una respuesta satisfactoria al clic son más complejos y requieren cierto conocimiento de la LRA que se usa en un dispositivo. Para obtener los mejores resultados, usa las formas de onda prefabricadas del dispositivo y las constantes proporcionadas por la plataforma, que te permiten hacer lo siguiente:
Concatenalos para componer nuevos efectos táctiles.
Estas constantes y primitivas táctiles predefinidas pueden acelerar mucho tu trabajo mientras creas efectos táctiles de alta calidad.
El contenido y las muestras de código que aparecen en esta página están sujetas a las licencias que se describen en la Licencia de Contenido. Java y OpenJDK son marcas registradas de Oracle o sus afiliados.
Última actualización: 2025-07-27 (UTC)
[null,null,["Última actualización: 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."]]