با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
رایج ترین محرک های ارتعاشی در دستگاه های اندرویدی ، محرک های تشدید خطی (LRAs) هستند. LRAها احساس کلیک روی یک دکمه را شبیه سازی می کنند که در غیر این صورت یک سطح شیشه ای بی پاسخ است. یک سیگنال بازخورد کلیک واضح و واضح معمولا بین 10 تا 20 میلی ثانیه طول می کشد. این حس باعث می شود که تعامل با کاربر طبیعی تر شود. برای صفحه کلیدهای مجازی، این بازخورد کلیک می تواند سرعت تایپ را افزایش داده و خطاها را کاهش دهد.
برخی از LRAها دارای فرکانس تشدید در محدوده 200 تا 300 هرتز بودند که با فرکانسی که پوست انسان در آن بیشترین حساسیت را به ارتعاش دارد همزمان است. احساس ارتعاشات در این محدوده فرکانس معمولاً به صورت صاف، تیز و نافذ توصیف می شود.
مدلهای دیگر LRA فرکانسهای تشدید پایینتری دارند، در حدود 150 هرتز. احساس از نظر کیفی نرمتر و پرتر (از نظر ابعاد) است.
اجزای یک محرک رزونانس خطی (LRA).
با توجه به ولتاژ ورودی یکسان در دو فرکانس مختلف، دامنه خروجی ارتعاش می تواند متفاوت باشد. هر چه فرکانس از فرکانس تشدید LRA دورتر باشد، دامنه ارتعاش آن کمتر است.
جلوه های لمسی یک دستگاه خاص از محرک لرزش و درایور آن استفاده می کند. درایورهای هپتیک که شامل ویژگیهای ترمز بیش از حد و فعال هستند، میتوانند زمان خیز و زنگ LRA را کاهش دهند و منجر به لرزش واضحتر و واکنشپذیرتر شوند.
شتاب خروجی ویبراتور
نگاشت شتاب فرکانس به خروجی (FOAM) حداکثر شتاب خروجی قابل دستیابی (در پیک G) را در یک فرکانس ارتعاش معین (به هرتز) توصیف می کند. با شروع Android 16 (سطح API 36)، این پلتفرم از طریق VibratorFrequencyProfile پشتیبانی داخلی برای این نقشه برداری ارائه می دهد. می توانید از این کلاس به همراه API های اولیه و پیشرفته envelope برای ایجاد جلوه های لمسی استفاده کنید.
اکثر موتورهای LRA دارای یک پیک واحد در فوم خود هستند که معمولاً نزدیک به فرکانس تشدیدشان است. به طور کلی با انحراف فرکانس از این محدوده، شتاب به طور تصاعدی کاهش می یابد. منحنی ممکن است متقارن نباشد و ممکن است دارای یک فلات در اطراف فرکانس تشدید برای محافظت از موتور در برابر آسیب باشد.
نمودار مجاور یک نمونه FOAM را برای یک موتور LRA نشان می دهد.
نمونه فوم برای یک موتور LRA.
آستانه تشخیص ادراک انسانی
آستانه تشخیص ادراک انسانی به حداقل شتاب یک ارتعاش اشاره دارد که یک فرد می تواند به طور قابل اعتماد تشخیص دهد. این سطح بر اساس فرکانس ارتعاش متفاوت است.
نمودار مجاور آستانه تشخیص ادراک لمسی انسان را در شتاب به عنوان تابعی از فرکانس زمانی نشان می دهد. داده های آستانه از آستانه جابجایی در شکل 1 از مقاله Bolanowski Jr., SJ, et al. در سال 1988، "چهار کانال واسطه جنبه های مکانیکی لمس" است. .
Android بهطور خودکار این آستانه را در BasicEnvelopeBuilder کنترل میکند، که تأیید میکند که همه افکتها از محدوده فرکانسی استفاده میکنند که دامنههای ارتعاشی را ایجاد میکند که حداقل ۱۰ دسیبل از آستانه تشخیص درک انسان فراتر میرود.
درک انسان از شدت ارتعاش، یک معیار ادراک ، با دامنه ارتعاش، یک پارامتر فیزیکی ، به صورت خطی رشد نمی کند. شدت درک شده با سطح حس (SL) مشخص می شود که به عنوان مقدار دسی بل بالاتر از آستانه تشخیص در همان فرکانس تعریف می شود.
دامنه شتاب ارتعاش مربوطه (در پیک G) را می توان به صورت زیر محاسبه کرد:
$$
Amplitude(G) = 10^{Amplitude(db)/20}
$$
... که در آن دامنه dB مجموع SL و آستانه تشخیص - مقدار در امتداد محور عمودی در نمودار مجاور - در یک فرکانس خاص است.
نمودار مجاور سطوح شتاب ارتعاش را در 10، 20، 30، 40 و 50 dB SL، همراه با آستانه تشخیص ادراک لمسی انسان (0dB SL)، به عنوان تابعی از فرکانس زمانی نشان می دهد. داده ها از شکل 8 در مقاله Verrillo، RT و همکاران در سال 1969، "قدرت حس محرک های ارتعاشی" برآورد شده است. .
سطوح شتاب ارتعاش
Android بهطور خودکار این تبدیل را در BasicEnvelopeBuilder انجام میدهد، که مقادیر را به صورت شدتهای عادی در فضای سطح حس (dB SL) میگیرد و آنها را به شتاب خروجی تبدیل میکند. از طرف دیگر، WaveformEnvelopeBuilder این تبدیل را اعمال نمی کند و به جای آن مقادیر را به عنوان دامنه شتاب خروجی نرمال شده در فضای شتاب (Gs) می گیرد. Envelope API فرض میکند که وقتی یک طراح یا توسعهدهنده به تغییرات در قدرت ارتعاش فکر میکند، انتظار دارند که شدت درک شده از یک پوشش خطی تکهای پیروی کند.
هموارسازی شکل موج پیش فرض در دستگاه ها
برای مثال، نحوه رفتار یک الگوی شکل موج سفارشی در یک دستگاه عمومی را در نظر بگیرید:
نمودارهای زیر شکل موج ورودی و شتاب خروجی مربوط به قطعه کد قبلی را نشان می دهد. توجه داشته باشید که شتاب به تدریج افزایش مییابد، نه ناگهانی، هر زمان که دامنه تغییر پلهای در الگو وجود دارد - یعنی در 0ms، 150ms، 200ms، 250ms و 700ms. همچنین در هر مرحله تغییر دامنه، یک افزایش بیش از حد وجود دارد و زمانی که دامنه ورودی ناگهان به 0 می رسد، زنگ قابل مشاهده ای وجود دارد که حداقل 50 میلی ثانیه طول می کشد.
نمودار شکل موج ورودی تابع پله.
نمودار شکل موج اندازهگیری شده واقعی، انتقال ارگانیک بیشتری را بین سطوح نشان میدهد.
الگوی لمسی بهبود یافته
برای جلوگیری از بیش از حد و کاهش زمان زنگ، دامنه ها را به تدریج تغییر دهید. شکل زیر نمودارهای شکل موج و شتاب نسخه اصلاح شده را نشان می دهد:
کاتلین
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 مورد استفاده در دستگاه نیاز دارند. برای بهترین نتیجه، از شکل موج های از پیش ساخته شده دستگاه و ثابت های ارائه شده توسط پلت فرم استفاده کنید که به شما امکان می دهد کارهای زیر را انجام دهید:
آنها را به هم متصل کنید تا جلوه های لمسی جدید بسازید.
این ثابت های لمسی و اولیه از پیش تعریف شده می توانند در عین ایجاد جلوه های لمسی با کیفیت بالا، سرعت کار شما را تا حد زیادی افزایش دهند.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[null,null,["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],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."]]