Оптимизируйте свои подборки
Сохраняйте и классифицируйте контент в соответствии со своими настройками.
Наиболее распространенными виброприводами на устройствах Android являются линейные резонансные приводы (LRA) . LRA имитируют ощущение нажатия кнопки на нереагирующей стеклянной поверхности. Ясный и четкий сигнал обратной связи щелчка обычно длится от 10 до 20 миллисекунд. Это ощущение делает взаимодействие пользователя более естественным. Для виртуальных клавиатур эта обратная связь щелчка может увеличить скорость печати и сократить количество ошибок.
Некоторые LRA имели резонансные частоты в диапазоне от 200 до 300 Гц, что совпадает с частотой, на которой кожа человека наиболее чувствительна к вибрации. Ощущение вибрации в этом диапазоне частот обычно описывается как плавное, резкое и проникающее.
Другие модели LRA имеют более низкие резонансные частоты, около 150 Гц. Ощущение качественно мягче и полнее (по объему).
Компоненты линейного резонансного привода (ЛРП).
При одинаковом входном напряжении на двух разных частотах амплитуды вибрации на выходе могут быть разными. Чем дальше частота от резонансной частоты LRA, тем ниже амплитуда ее вибрации.
Тактильные эффекты данного устройства используют как вибропривод, так и его драйвер. Тактильные драйверы, включающие функции овердрайва и активного торможения, могут сократить время нарастания и звон LRA, что приводит к более отзывчивой и четкой вибрации.
Ускорение выходного сигнала вибратора
Отображение частоты к выходному ускорению (FOAM) описывает максимально достижимое выходное ускорение (в пике G) при заданной частоте вибрации (в герцах). Начиная с Android 16 (уровень API 36), платформа предоставляет встроенную поддержку этого отображения через VibratorFrequencyProfile . Вы можете использовать этот класс вместе с базовыми и расширенными API-интерфейсами огибающей для создания тактильных эффектов.
Большинство двигателей LRA имеют один пик в FOAM, обычно вблизи резонансной частоты. Ускорение обычно уменьшается экспоненциально по мере отклонения частоты от этого диапазона. Кривая может быть несимметричной и может иметь плато около резонансной частоты для защиты двигателя от повреждения.
На соседнем графике показан пример ПЕНЫ для двигателя LRA.
Пример ПЕНЫ для двигателя LRA.
Порог обнаружения человеческого восприятия
Порог обнаружения человеческого восприятия относится к минимальному ускорению вибрации, которое человек может надежно обнаружить. Этот уровень варьируется в зависимости от частоты вибрации.
Соседний график показывает порог обнаружения человеческого тактильного восприятия, при ускорении, как функцию временной частоты. Пороговые данные преобразованы из порога смещения на рисунке 1 статьи Bolanowski Jr., SJ, et al. 1988 года "Четыре канала опосредуют механические аспекты прикосновения" .
Android автоматически обрабатывает этот порог в BasicEnvelopeBuilder , который проверяет, что все эффекты используют диапазон частот, который создает амплитуды вибрации, превышающие порог обнаружения человеческого восприятия как минимум на 10 дБ.
Порог обнаружения тактильного восприятия человека.
Человеческое восприятие интенсивности вибрации, мера восприятия , не растет линейно с амплитудой вибрации, физическим параметром. Воспринимаемая интенсивность характеризуется уровнем чувствительности (УО), который определяется как величина дБ выше порога обнаружения на той же частоте.
Соответствующую амплитуду ускорения вибрации (в пике G) можно рассчитать следующим образом:
$$
Amplitude(G) = 10^{Amplitude(db)/20}
$$
...где амплитуда дБ представляет собой сумму SL и порога обнаружения — значения по вертикальной оси на соседнем графике — на определенной частоте.
На соседнем графике показаны уровни ускорения вибрации при 10, 20, 30, 40 и 50 дБ SL, а также порог обнаружения тактильного восприятия человека (0 дБ SL) в зависимости от временной частоты. Данные получены с помощью рисунка 8 в статье Verrillo, RT, et al. 1969 года «Величина ощущения вибротактильных стимулов» .
Уровни ускорения вибрации.
Android автоматически обрабатывает это преобразование в BasicEnvelopeBuilder , который принимает значения как нормализованные интенсивности в пространстве уровня ощущений (dB SL) и преобразует их в выходное ускорение. WaveformEnvelopeBuilder , с другой стороны, не применяет это преобразование и вместо этого принимает значения как нормализованные амплитуды выходного ускорения в пространстве ускорения (Gs). API огибающей предполагает, что когда проектировщик или разработчик думает об изменениях силы вибрации, они ожидают, что воспринимаемая интенсивность будет следовать кусочно-линейной огибающей.
Сглаживание формы волны по умолчанию на устройствах
Для иллюстрации рассмотрим, как ведет себя пользовательский шаблон формы волны на стандартном устройстве:
На следующих графиках показана входная форма волны и выходное ускорение, соответствующие предыдущим фрагментам кода. Обратите внимание, что ускорение увеличивается постепенно, а не внезапно, всякий раз, когда в шаблоне происходит ступенчатое изменение амплитуды, то есть при 0 мс, 150 мс, 200 мс, 250 мс и 700 мс. Также наблюдается выброс при каждом ступенчатом изменении амплитуды, и наблюдается видимый звон, который длится не менее 50 мс, когда входная амплитуда внезапно падает до 0.
График формы входного сигнала ступенчатой функции.
График фактической измеренной формы волны, показывающий более органичные переходы между уровнями.
Улучшенный тактильный рисунок
Чтобы избежать перерегулирования и сократить время звона, изменяйте амплитуды более плавно. Ниже показаны графики формы волны и ускорения пересмотренной версии:
Котлин
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))
Ява
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));
График входного сигнала с дополнительными шагами.
График измеренной формы сигнала, показывающий более плавные переходы.
Создавайте более сложные тактильные эффекты
Другие элементы в удовлетворительном отклике на щелчок более сложны, требуя некоторых знаний о LRA, используемом в устройстве. Для достижения наилучших результатов используйте предварительно подготовленные формы волн устройства и константы, предоставляемые платформой, которые позволяют вам делать следующее:
Объединяйте их, чтобы создавать новые тактильные эффекты.
Эти предопределенные тактильные константы и примитивы могут значительно ускорить вашу работу, создавая высококачественные тактильные эффекты.
Контент и образцы кода на этой странице предоставлены по лицензиям. Java и OpenJDK – это зарегистрированные товарные знаки корпорации Oracle и ее аффилированных лиц.
Последнее обновление: 2025-07-29 UTC.
[null,null,["Последнее обновление: 2025-07-29 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."]]