Android
 Computer >> コンピューター >  >> プログラミング >> Android

Androidアプリでスマホのシェイク(振る)イベントを検出する方法を解説

この記事では、Androidアプリでスマートフォンが「振られた(シェイク)」ことを加速度センサーを使って検出する方法を、実際のサンプルコードとともにステップごとに解説します。

シェイクイベント検出の仕組み

Android端末には加速度センサー(Accelerometer)が搭載されており、端末の動きや傾きを検知できます。センサーの値から加速度の変化量を計算し、一定のしきい値を超えたら「シェイクイベント」として判定するのが基本的な実装方法です。

実装手順

ステップ1:新規プロジェクトを作成する

Android Studioを開き、「File → New Project」から新しいプロジェクトを作成します。必要な項目をすべて入力してプロジェクトを完成させましょう。

ステップ2:レイアウトファイル(activity_main.xml)を編集する

res/layout/activity_main.xml に以下のコードを追加します。画面には「スマホを振るとシェイクイベントを検出します」という案内テキストを表示しています。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <TextView
        android:text="Shake the phone to detect to shake event"
        android:textSize="24sp"
        android:textStyle="bold"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

ステップ3:MainActivity.java にセンサー処理を実装する

src/MainActivity.java に以下のコードを記述します。ポイントは以下の通りです。

  • SensorManager を取得し、加速度センサー(TYPE_ACCELEROMETER)のリスナーを登録
  • onSensorChanged() 内で X・Y・Z 軸それぞれの加速度値を取得
  • 前回値との差分(delta)を計算し、ローパスフィルタのように係数0.9で平滑化
  • 合成加速度 mAccel が 12 を超えたらシェイクイベントと判定し、Toastで通知
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.Toast;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
    private SensorManager mSensorManager;
    private float mAccel;
    private float mAccelCurrent;
    private float mAccelLast;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        Objects.requireNonNull(mSensorManager).registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
        SensorManager.SENSOR_DELAY_NORMAL);
        mAccel = 10f;
        mAccelCurrent = SensorManager.GRAVITY_EARTH;
        mAccelLast = SensorManager.GRAVITY_EARTH;
    }
    private final SensorEventListener mSensorListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];
            mAccelLast = mAccelCurrent;
            mAccelCurrent = (float) Math.sqrt((double) (x * x + y * y + z * z));
            float delta = mAccelCurrent - mAccelLast;
            mAccel = mAccel * 0.9f + delta;
            if (mAccel > 12) {
                Toast.makeText(getApplicationContext(), "Shake event detected", Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }
    };
    @Override
    protected void onResume() {
        mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
        SensorManager.SENSOR_DELAY_NORMAL);
        super.onResume();
    }
    @Override
    protected void onPause() {
        mSensorManager.unregisterListener(mSensorListener);
        super.onPause();
    }
}

なお、onResume() でリスナーを再登録し、onPause() で解除している点も重要です。これにより、アプリがバックグラウンドにある間は不要なセンサー処理を停止でき、バッテリー消費を抑えられます。

ステップ4:AndroidManifest.xml を確認する

androidManifest.xml には以下のコードを記述します。加速度センサーは特別なパーミッションが不要なため、通常のマニフェスト定義だけで動作します。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.com.sample">
    <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">
            <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
        </activity>
    </application>
</manifest>

アプリを実行して動作を確認する

それでは、実際にアプリを起動してみましょう。Android端末をPCに接続した状態で、Android Studioのツールバーにある実行(Run)アイコンをクリックします。デバイス選択画面で自分のスマートフォンを選択すると、端末にデフォルト画面が表示されます。

ここでスマホを実際に振ってみてください。加速度の変化量がしきい値を超えると、画面に「Shake event detected」というトーストメッセージが表示され、シェイクイベントが正しく検出されていることが確認できます。

Androidアプリでスマホのシェイク(振る)イベントを検出する方法を解説

まとめ

Androidでシェイクイベントを検出するには、加速度センサーの値を監視し、変化量がしきい値を超えたかどうかを判定します。しきい値(本例では12)や平滑化の係数(0.9)を調整することで、感度の微調整も可能です。シェイク操作は「振って戻す」「振って更新」などのユーザーインタラクションに活用できるので、ぜひ自分のアプリにも取り入れてみてください。

  1. FacebookでAndroidアプリを作成する方法|開発者サイトでの設定手順を徹底解説

    この記事では、FacebookでAndroidアプリを作成する方法について詳しく解説します。AndroidアプリとFacebookを連携させるには、Facebook開発者サイトでFacebookアプリを作成し、Facebook App IDを取得する必要があります。以下の手順に従って、順番に進めていきましょう。 準備:Facebook開発者サイトで新しいアプリを追加する まず、https://developers.facebook.com/ にアクセスし、「新しいアプリを追加」をクリックしてアプリの作成を開始します。 ステップ1:アプリ名とメールアドレスを入力する 指定されたフィールドに、作

  2. 【Android】5秒間のユーザー非アクティブ(無操作)を検出する方法を解説

    はじめに 本記事では、Androidアプリでユーザーが5秒間何も操作しなかったこと(非アクティブ状態)を検出する方法を、サンプルコードとともに解説します。 鍵となるのは、Activityクラスに標準で用意されているonUserInteraction()コールバックです。このメソッドはタップやスワイプなど、ユーザーが画面を操作するたびに呼び出されるため、Handlerと組み合わせることで「最後の操作からの経過時間」を簡単に計測できます。 手順1:新規プロジェクトを作成する Android Studioを起動し、メニューから「File」→「New Project」を選択します。必要事項を入力して、