קל לארגן דפים בעזרת אוספים
אפשר לשמור ולסווג תוכן על סמך ההעדפות שלך.
רכיבי האקטואטור הנפוצים ביותר ליצירת רטט במכשירי Android הם רכיבי אקטואטור לינאריים בתהודה (LRA). רכיבי LRA מדמים את התחושה של לחיצה על לחצן במשטח זכוכית שלא מגיב. בדרך כלל, אות משוב ברור ותקיף של קליקים נמשך בין 10 ל-20 אלפיות שנייה. כך האינטראקציות של המשתמשים נראות טבעיות יותר. במקלדות וירטואליות, משוב הקליקים יכול להגדיל את מהירות ההקלדה ולצמצם את מספר השגיאות.
לחלק מה-LRA היו תדרי תהודה בטווח של 200 עד 300 Hz, שתואמים לתדר שבו העור האנושי רגיש ביותר לתנודות. בדרך כלל, התחושה של הרטט בטווח התדרים הזה מתוארת כחלקה, חדה וחודרת.
לדגמים אחרים של רמקול נייד יש תדרי תהודה נמוכים יותר, בסביבות 150 Hz. התחושה איכותית יותר, רכה יותר ומלאה יותר (במימד).
רכיבים של מפעיל רטט לינארי (LRA).
אם מתקבל אותו מתח קלט בשתי תדרים שונים, יכול להיות שהאמפליטודות של תפוקת הרטט יהיו שונות. ככל שהתדר רחוק יותר מתדר התהודה של ה-LRA, כך אמפליטודת הרטט שלו נמוכה יותר.
האפקטים ההדדיים של מכשיר נתון משתמשים גם במפעיל הרטט וגם בדרייבר שלו.
מנהלי התקנים של משוב מגע שכוללים תכונות של מצב אוברדרייב ותכונות של בלימה פעילה יכולים לצמצם את זמן העלייה ואת הצלצול של רכיבי LRA, וכך להוביל לרטט מהיר וברור יותר.
האצת הפלט של הרטט
המיפוי של תדירות לתאוצה בפלט (FOAM) מתאר את תאוצת הפלט המקסימלית שניתן להשיג (ב-G שיא) בתדירות רטט נתונה (בהרץ). החל מגרסה Android 16 (רמת API 36), הפלטפורמה מספקת תמיכה מובנית במיפוי הזה באמצעות VibratorFrequencyProfile. אפשר להשתמש בכיתה הזו, יחד עם ממשקי ה-API של המעטפות הבסיסיים והמתקדמים, כדי ליצור אפקטים של משוב מישוש.
לרוב המנועים מסוג LRA יש שיא יחיד ב-FOAM, בדרך כלל ליד תדר התהודה שלהם. בדרך כלל, ההאצה פוחתת באופן אקספוננציאלי ככל שהתדר חורג מהטווח הזה. העקומה עשויה להיות לא סימטרית, ויכול להיות שתופיע בה פסגה סביב תדר התהודה כדי להגן על המנוע מפני נזק.
בתרשים שלצידו מוצגת דוגמה ל-FOAM למנוע LRA.
דוגמה ל-FOAM למנוע LRA.
סף לזיהוי על ידי אדם
סף הגילוי של תפיסת האדם מתייחס לתאוצה המינימלית של רטט שאדם יכול לזהות באופן מהימן. רמת הרטט משתנה בהתאם לתדירות הרטט.
בתרשים שלצידו מוצג סף הזיהוי של תפיסת המגע האנושית, בתאוצה, כפונקציה של תדירות זמנית. נתוני הסף הופכים מסף ההזזה שמוצג באיור 1 במאמר של Bolanowski Jr., S. J., et
al.'s 1988 article,
"Four channels mediate the mechanical aspects of touch.".
Android מטפלת באופן אוטומטי בערך הסף הזה ב-BasicEnvelopeBuilder, ומאמתת שכל האפקטים משתמשים בטווח תדרים שמייצר אמפליטודות של רטט שעולות על ערך הסף לזיהוי בתפיסה האנושית ב-10 dB לפחות.
התפיסה האנושית של עוצמת הרטט, שהיא מדד של תפיסה, לא גדלה באופן לינארי עם אמפליטודת הרטט, שהיא פרמטר פיזי. עוצמת הקול שמורגשת מאופיינת ברמת החישה (SL), שמוגדר כערך הדציבלים מעל סף הזיהוי באותה תדירות.
אפשר לחשב את אמפליטודת האצה התואמת של הרטט (ב-G שיא) באופן הבא:
$$
Amplitude(G) = 10^{Amplitude(db)/20}
$$
...כאשר עוצמת המתח ב-dB היא הסכום של SL וסף הזיהוי – הערך שמוצג בציר האנכי בתרשים הסמוך – בתדר מסוים.
בתרשים הסמוך מוצגים רמות האצה של רטט ב-10, 20, 30, 40 ו-50 dB SL, לצד סף הזיהוי של תפיסת המגע האנושית (0 dB SL), בתור פונקציה של תדירות זמנית. הנתונים משוערים לפי איור 8 במאמר של Verrillo, R. המאמר של T. et al. משנת 1969, "Sensation magnitude of vibrotactile stimuli".
רמות האצה של הרטט.
מערכת Android מטפלת בהמרה הזו באופן אוטומטי ב-BasicEnvelopeBuilder, שמקבלת ערכים כעוצמות מנורמלות במרחב רמת החישה (dB SL) וממירה אותם לאולטרה-סאונד. לעומת זאת, הפונקציה WaveformEnvelopeBuilder לא מחילה את ההמרה הזו, ובמקום זאת מקבלת ערכים כערכי אמפליטודה של תאוצה רגילה בפלט במרחב התאוצה (Gs). כשמעצבים או מפתחים חושבים על שינויים בעוצמת הרטט, הם מצפים שהעוצמה הנתפסת תעקוב אחרי מעטפת לינארית חלקית.
החלקת צורת הגל שמוגדרת כברירת מחדל במכשירים
כדי להמחיש את העניין, נבחן את האופן שבו תבנית גל מותאמת אישית מתנהגת במכשיר כללי:
בתרשים הבא מוצגים צורת הגל של הקלט והתאוצה של הפלט בהתאם לקטע הקוד הקודם. שימו לב שהתאוצה עולה בהדרגה, ולא באופן פתאומי, בכל פעם שיש שינוי פתאומי באמפליטודה של התבנית – כלומר, ב-0ms, 150ms, 200ms, 250ms ו-700ms. יש גם חריגה מעל הערך הרצוי בכל שינוי שלב של האמפליטודה, ויש צלצול גלוי שנמשך לפחות 50 אלפיות השנייה כשאמפליטודת הקלט יורדת באופן פתאומי ל-0.
תרשים של צורת הגל של הקלט של פונקציית הצעד.
תרשים של צורת הגל שנמדדה בפועל, שבו מוצגים יותר מעברים אורגניים בין רמות.
דפוס רטט משופר
כדי להימנע מתנודות יתר ולקצר את זמן הצלצול, צריך לשנות את האמפליטודות באופן הדרגתי יותר. בתרשים הבא מוצגים תרשים הגל והתאוצה של הגרסה המתוקנת:
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));
תרשים של צורת הגל של הקלט עם שלבים נוספים.
תרשים של צורת הגל שנמדדה, שבו מוצגים מעברים חלקים יותר.
יצירת אפקטים מורכבים יותר של משוב מישוש
רכיבים אחרים בתגובה הולמת ללחיצה מורכבים יותר, ודורשים ידע מסוים ב-LRA שנעשה בו שימוש במכשיר. כדי לקבל את התוצאות הטובות ביותר, מומלץ להשתמש בצורות הגל המוכנות מראש ובקבועים שסופקו על ידי הפלטפורמה של המכשיר. כך תוכלו:
קבועים ופרימיטיבים של משוב מגע מוגדרים מראש יכולים להאיץ את העבודה שלכם מאוד בזמן יצירת אפקטים של משוב מגע באיכות גבוהה.
דוגמאות התוכן והקוד שבדף הזה כפופות לרישיונות המפורטים בקטע רישיון לתוכן. Java ו-OpenJDK הם סימנים מסחריים או סימנים מסחריים רשומים של חברת Oracle ו/או של השותפים העצמאיים שלה.
עדכון אחרון: 2025-07-27 (שעון UTC).
[[["התוכן קל להבנה","easyToUnderstand","thumb-up"],["התוכן עזר לי לפתור בעיה","solvedMyProblem","thumb-up"],["סיבה אחרת","otherUp","thumb-up"]],[["חסרים לי מידע או פרטים","missingTheInformationINeed","thumb-down"],["התוכן מורכב מדי או עם יותר מדי שלבים","tooComplicatedTooManySteps","thumb-down"],["התוכן לא עדכני","outOfDate","thumb-down"],["בעיה בתרגום","translationIssue","thumb-down"],["בעיה בדוגמאות/בקוד","samplesCodeIssue","thumb-down"],["סיבה אחרת","otherDown","thumb-down"]],["עדכון אחרון: 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."]]