Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Các bộ truyền động rung phổ biến nhất trên thiết bị Android là bộ truyền động cộng hưởng tuyến tính (LRA). LRA mô phỏng cảm giác nhấp vào nút trên một bề mặt kính không phản hồi. Tín hiệu phản hồi lượt nhấp rõ ràng và sắc nét thường kéo dài từ 10 đến 20 mili giây. Cảm giác này giúp người dùng tương tác một cách tự nhiên hơn. Đối với bàn phím ảo, phản hồi lượt nhấp này có thể tăng tốc độ nhập và giảm lỗi.
Một số LRA có tần số cộng hưởng trong khoảng từ 200 đến 300 Hz, trùng khớp với tần số mà da người nhạy cảm nhất với độ rung. Cảm giác rung ở dải tần số này thường được mô tả là mượt mà, sắc nét và xuyên thấu.
Các mẫu LRA khác có tần số cộng hưởng thấp hơn, khoảng 150 Hz. Cảm giác về chất lượng mềm hơn và đầy đặn hơn (theo chiều).
Các thành phần của một bộ truyền động cộng hưởng tuyến tính (LRA).
Với cùng một điện áp đầu vào ở hai tần số khác nhau, biên độ đầu ra của độ rung có thể khác nhau. Tần số càng xa tần số cộng hưởng của LRA, biên độ dao động càng thấp.
Hiệu ứng xúc giác của một thiết bị cụ thể sử dụng cả bộ truyền động rung và trình điều khiển của bộ truyền động đó.
Trình điều khiển haptics có các tính năng tăng tốc và phanh chủ động có thể giảm thời gian tăng và độ rung của LRA, giúp độ rung rõ ràng và nhạy hơn.
Gia tốc đầu ra của bộ rung
Bản đồ tần số-tốc độ tăng tốc đầu ra (FOAM) mô tả tốc độ tăng tốc đầu ra tối đa có thể đạt được (tính bằng G đỉnh) ở một tần số rung nhất định (tính bằng Hertz). Kể từ Android 16 (API cấp 36), nền tảng này sẽ tích hợp tính năng hỗ trợ cho việc liên kết này thông qua VibratorFrequencyProfile. Bạn có thể sử dụng lớp này cùng với các API phong bì cơ bản và nâng cao để tạo hiệu ứng xúc giác.
Hầu hết động cơ LRA đều có một đỉnh duy nhất trong FOAM, thường là gần tần số cộng hưởng. Gia tốc thường giảm theo hàm mũ khi tần số sai lệch khỏi phạm vi này. Đường cong có thể không đối xứng và có thể có một vùng phẳng quanh tần số cộng hưởng để bảo vệ động cơ khỏi bị hư hỏng.
Biểu đồ bên cạnh cho thấy một ví dụ về FOAM cho động cơ LRA.
Ví dụ về FOAM cho động cơ LRA.
Ngưỡng phát hiện nhận thức của con người
Ngưỡng phát hiện cảm nhận của con người đề cập đến gia tốc tối thiểu của một dao động mà một người có thể phát hiện một cách đáng tin cậy. Mức này thay đổi tuỳ theo tần suất rung.
Biểu đồ bên cạnh cho thấy ngưỡng phát hiện cảm nhận xúc giác của con người, tính theo gia tốc, dưới dạng hàm tần số thời gian. Dữ liệu ngưỡng được chuyển đổi từ ngưỡng dịch chuyển trong Hình 1 của Bolanowski Jr., S. Bài viết năm 1988 của J., et
al.,
"Bốn kênh điều tiết các khía cạnh cơ học của cảm ứng".
Android tự động xử lý ngưỡng này trong BasicEnvelopeBuilder, xác minh rằng tất cả các hiệu ứng đều sử dụng phạm vi tần số tạo ra biên độ rung vượt quá ngưỡng phát hiện nhận thức của con người ít nhất là 10 dB.
Nhận thức của con người về cường độ rung, một phép đo nhận thức, không tăng lên một cách tuyến tính với biên độ rung, một tham số vật lý. Cường độ cảm nhận được đặc trưng bằng mức độ cảm giác (SL), được xác định là một lượng dB cao hơn ngưỡng phát hiện ở cùng tần số.
Bạn có thể tính toán biên độ gia tốc rung tương ứng (tính bằng G đỉnh) như sau:
$$
Amplitude(G) = 10^{Amplitude(db)/20}
$$
...trong đó dB biên độ là tổng của SL và ngưỡng phát hiện – giá trị dọc theo trục dọc trong biểu đồ liền kề – ở một tần số cụ thể.
Biểu đồ bên cạnh cho thấy các mức gia tốc rung ở 10, 20, 30, 40 và 50 dB SL, cùng với ngưỡng phát hiện cảm nhận xúc giác của con người (0 dB SL), dưới dạng hàm của tần số thời gian. Dữ liệu được ước tính từ Hình 8 trong bài viết của Verrillo, R. Bài viết năm 1969 của T., et al., "Mức độ cảm giác của các kích thích rung xúc giác.".
Các cấp độ gia tốc rung.
Android tự động xử lý việc chuyển đổi này trong BasicEnvelopeBuilder, lấy các giá trị dưới dạng cường độ chuẩn hoá trong không gian mức độ cảm giác (dB SL) và chuyển đổi các giá trị đó thành gia tốc đầu ra. Mặt khác, WaveformEnvelopeBuilder không áp dụng phép chuyển đổi này và lấy các giá trị dưới dạng biên độ gia tốc đầu ra đã chuẩn hoá trong không gian gia tốc (G). API bao bì giả định rằng khi nhà thiết kế hoặc nhà phát triển nghĩ về những thay đổi về cường độ rung, họ mong đợi cường độ cảm nhận được sẽ tuân theo một bao bì tuyến tính theo từng phần.
Làm mượt dạng sóng mặc định trên thiết bị
Để minh hoạ, hãy xem xét cách hoạt động của mẫu dạng sóng tuỳ chỉnh trên một thiết bị chung:
Các biểu đồ sau đây cho thấy dạng sóng đầu vào và gia tốc đầu ra tương ứng với các đoạn mã trước đó. Lưu ý rằng gia tốc tăng dần, chứ không đột ngột, bất cứ khi nào có sự thay đổi bước của biên độ trong mẫu, tức là tại 0 mili giây, 150 mili giây, 200 mili giây, 250 mili giây và 700 mili giây. Ngoài ra, còn có hiện tượng vượt quá ở mỗi bước thay đổi biên độ và có hiện tượng rung rõ ràng kéo dài ít nhất 50 mili giây khi biên độ đầu vào đột ngột giảm xuống 0.
Biểu đồ dạng sóng đầu vào của hàm bước.
Biểu đồ dạng sóng đo lường thực tế, cho thấy các chuyển đổi tự nhiên hơn
giữa các cấp.
Cải thiện mẫu haptics
Để tránh vượt quá và giảm thời gian đổ chuông, hãy thay đổi biên độ một cách từ từ hơn. Sau đây là đồ thị dạng sóng và gia tốc của phiên bản sửa đổi:
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));
Biểu đồ dạng sóng đầu vào với các bước bổ sung.
Biểu đồ dạng sóng được đo lường, cho thấy các chuyển đổi mượt mà hơn.
Tạo hiệu ứng xúc giác phức tạp hơn
Các thành phần khác trong phản hồi nhấp chuột thoả đáng phức tạp hơn, đòi hỏi một số kiến thức về LRA được sử dụng trong thiết bị. Để có kết quả tốt nhất, hãy sử dụng sóng được tạo sẵn và hằng số do nền tảng cung cấp của thiết bị. Điều này cho phép bạn làm những việc sau:
Kết hợp các hiệu ứng này để tạo hiệu ứng xúc giác mới.
Các hằng số và nguyên hàm xúc giác được xác định trước này có thể giúp bạn tăng tốc đáng kể trong khi tạo hiệu ứng xúc giác chất lượng cao.
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-07-27 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 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."]]