首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Android 實現搖一搖觸發震動效果完整指南

     編輯:Java 相關知識

早期微信「搖一搖」功能風靡一時,許多開發者也想在自家 App 中加入類似的互動體驗。本文將從加速度感測器原理出發,手把手教你完成一個「搖一搖觸發手機震動」的 Demo,並解析關鍵 API 與權限設定。

一、核心原理:加速度感測器與閾值判斷

Android 手機內建多種感測器,實現搖一搖主要依賴 加速度感測器。當使用者搖晃手機時,三軸加速度值會瞬間飆升;我們只需在 SensorEventListener.onSensorChanged() 中監聽三軸數值,若任一軸絕對值超過預設閾值(如 20 m/s²),即判定為「搖動事件」,進而觸發震動或其他業務邏輯。

二、感測器使用三步曲

  1. 取得 SensorManager 系統服務。
  2. 實作 SensorEventListener 介面,覆寫 onSensorChanged() 與 onAccuracyChanged()。
  3. 呼叫 SensorManager.registerListener() 註冊監聽器,指定感測器類型為 Sensor.TYPE_ACCELEROMETER。

三、震動服務 Vibrator 使用詳解

Android 震動功能由 Vibrator 系統服務提供,需在 AndroidManifest.xml 宣告權限:

<uses-permission android:name="android.permission.VIBRATE"/>

常用兩種震動模式:

  • 單次震動: vibrator.vibrate(milliseconds),參數為震動持續時間(毫秒)。
  • 自訂模式: vibrator.vibrate(pattern, repeat),pattern 為 long 陣列,意義為 [靜止時間, 震動時間, 靜止時間, 震動時間...];repeat 為 -1 表示不重複,索引值表示從該索引開始循環。
public class VibratorHelper {
    public static void vibrateOnce(Activity activity, long milliseconds) {
        Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(milliseconds);
    }

    public static void vibratePattern(Activity activity, long[] pattern, int repeat) {
        Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(pattern, repeat);
    }
}

四、完整 Demo 程式碼

public class MainActivity extends Activity {
    private SensorManager sensorManager;
    private SensorEventListener shakeListener;
    private AlertDialog.Builder dialogBuilder;
    private boolean isRefresh = false; // 防止重複觸發

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        shakeListener = new ShakeSensorListener();
        dialogBuilder = new AlertDialog.Builder(this);
        dialogBuilder.setPositiveButton("確定", (dialog, which) -> {
            isRefresh = false;
            dialog.cancel();
        }).setMessage("搖到了一位帥氣小哥哥!").create();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 註冊監聽器,採用最快更新速率
        sensorManager.registerListener(shakeListener,
                sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_FASTEST);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Activity 進入背景時解除註冊,省電
        sensorManager.unregisterListener(shakeListener);
    }

    private class ShakeSensorListener implements SensorEventListener {
        private static final int SHAKE_THRESHOLD = 20; // 閾值可依實測調整

        @Override
        public void onSensorChanged(SensorEvent event) {
            if (isRefresh) return; // 正在處理中,忽略

            float x = Math.abs(event.values[0]);
            float y = Math.abs(event.values[1]);
            float z = Math.abs(event.values[2]);

            if (x >= SHAKE_THRESHOLD || y >= SHAKE_THRESHOLD || z >= SHAKE_THRESHOLD) {
                Toast.makeText(MainActivity.this, "加速度: " + Math.max(x, Math.max(y, z)), Toast.LENGTH_SHORT).show();
                VibratorHelper.vibrateOnce(MainActivity.this, 300);
                isRefresh = true;
                dialogBuilder.show();
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            // 精度變更時處理,通常不需理會
        }
    }
}

五、實務調優建議

  • 閾值校準: 不同機型感測器靈敏度不同,建議提供使用者自訂閾值或採用動態校準演算法。
  • 去抖動: 觸發後設定冷卻時間(如 1 秒),避免連續觸發。
  • 生命週期管理: 一定要在 onPause() 解除註冊,否則會導致記憶體洩漏與耗電。

掌握感測器與震動服務的串接,即可為 App 增加豐富的體感互動體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved