Giới thiệu về dịch vụ Rung (Vibrator)
Android cung cấp dịch vụ hệ thống Vibrator để điều khiển motor rung của thiết bị. Từ API 26 (Android 8.0), cần sử dụng VibrationEffect thay cho phương thức cũ.
Cần quyền VIBRATE trong AndroidManifest.xml.
Ví dụ hoàn chỉnh
Bước 1: Tạo project
Android Studio → File → New Project.
Bước 2: Layout (res/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@+id/parent"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:gravity="center"
android:background="#33FFFF00"
android:orientation="vertical">
<TextView
android:id="@+id/text"
android:textSize="18sp"
android:text="Click here to vibrate"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Bước 3: Code (src/MainActivity.java)
package com.example.andy.myapplication;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final LinearLayout parent = findViewById(R.id.parent);
textView = findViewById(R.id.text);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator == null || !vibrator.hasVibrator()) {
textView.setText("Thiết bị không hỗ trợ rung");
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// API 26+ sử dụng VibrationEffect
vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
// API cũ
vibrator.vibrate(500);
}
}
});
}
}
Bước 4: AndroidManifest.xml - Thêm quyền
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.andy.myapplication">
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Các mẫu rung nâng cao (API 26+)
Rung một lần (One-shot)
// 500ms, amplitude mặc định vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)); // Tùy chỉnh amplitude (1-255) vibrator.vibrate(VibrationEffect.createOneShot(1000, 128));
Rung theo mẫu (Pattern)
// Pattern: {delay, rung, delay, rung, ...}
// Rung 200ms, nghỉ 100ms, rung 300ms
long[] pattern = {0, 200, 100, 300};
vibrator.vibrate(VibrationEffect.createWaveform(pattern, -1)); // -1 = không lặp
// Lặp lại từ index 2
vibrator.vibrate(VibrationEffect.createWaveform(pattern, 2));
Rung nhịp điệu (Predefined effects - API 29+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Hiệu ứng click nhẹ
vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
// Hiệu ứng double click
vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK));
// Hiệu ứng tick (như bàn phím)
vibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK));
}
Kiểm tra hỗ trợ rung
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
boolean hasVibrator = vibrator != null && vibrator.hasVibrator();
// API 29+ kiểm tra amplitude control
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
boolean hasAmplitudeControl = vibrator.hasAmplitudeControl();
}
Hủy rung
// Hủy tất cả rung đang diễn ra vibrator.cancel();
Lưu ý quan trọng
- Luôn kiểm tra
hasVibrator()trước khi rung - Quyền
VIBRATElà normal permission (tự động cấp) - Rung quá nhiều tiêu tốn pin
- Một số thiết bị không có motor rung
- API 26+ khuyến khích dùng
VibrationEffect