Skip to content

Instantly share code, notes, and snippets.

@LeoAndo
Last active October 3, 2023 09:02
Show Gist options
  • Save LeoAndo/75f79d7e5fc2a0fd9dcc9547ed06e571 to your computer and use it in GitHub Desktop.
Save LeoAndo/75f79d7e5fc2a0fd9dcc9547ed06e571 to your computer and use it in GitHub Desktop.
[Android] 画面のライフサイクルに対応するサウンドクラス
package xxx; // TODO 環境に合わせて変更してください
import android.content.Context;
import android.media.AudioAttributes;
import android.media.SoundPool;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
/**
* 画面のライフサイクルに対応するサウンドクラス.
*/
public class MainSoundPlayer implements DefaultLifecycleObserver {
private static final String LOG_TAG = MainSoundPlayer.class.getSimpleName();
private static final float LEFT_VOLUME_VALUE = 1.0f; // left volume value (range = 0.0 to 1.0)
private static final float RIGHT_VOLUME_VALUE = 1.0f;// right volume value (range = 0.0 to 1.0)
private static final int SOUND_LOOP_MODE_NO_LOOP = 0; // loop mode (0 = no loop, -1 = loop forever)
private static final float SOUND_PLAY_BACK_RATE = 1.0f; // playback rate (1.0 = normal playback, range 0.5 to 2.0)
private static final int PRIORITY_1 = 1;
private final SoundPool soundPool;
private final int clappingSoundId;
private int clappingStreamId;
public MainSoundPlayer(Context context) {
final AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
final int maxStreams = 1; // TODO ストリーム数 (適宜変更してください)
soundPool = new SoundPool.Builder()
.setAudioAttributes(audioAttributes)
.setMaxStreams(maxStreams)
.build();
clappingSoundId = soundPool.load(context, R.raw.clapping, PRIORITY_1); // TODO: R.raw.xxx は自分の環境に合わせてください
}
// 効果音を再生する
public void playClappingSound() {
clappingStreamId = soundPool.play(
clappingSoundId, LEFT_VOLUME_VALUE, RIGHT_VOLUME_VALUE,
PRIORITY_1, SOUND_LOOP_MODE_NO_LOOP, SOUND_PLAY_BACK_RATE);
}
// 効果音を停止する
public void stopClappingSound() {
soundPool.stop(clappingStreamId);
}
// 画面表示時に呼ばれる
@Override
public void onResume(@NonNull LifecycleOwner owner) {
Log.d(LOG_TAG, "call onResume");
if (soundPool == null) return;
soundPool.autoResume(); // soundPool.autoPause()したときにアクティブだったすべての音声ファイルを再生する.
}
// 画面非表示時に呼ばれる
@Override
public void onPause(@NonNull LifecycleOwner owner) {
Log.d(LOG_TAG, "call onPause");
if (soundPool == null) return;
soundPool.autoPause(); // 全ての再生中の音声ファイルを停止する.
}
// 画面終了時に呼ばれる
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
Log.d(LOG_TAG, "call onDestroy release soundPool: " + soundPool);
if (soundPool == null) return;
soundPool.release(); // SoundPoolによって使用されているすべてのメモリとネイティブリソースを解放する.
}
}
@LeoAndo
Copy link
Author

LeoAndo commented Oct 3, 2023

使用した効果音データ

https://taira-komori.jpn.org/human01.html
スクリーンショット 2023-10-03 17 58 40

使い方

rawディレクトリをres配下に作成する

スクリーンショット 2023-10-03 17 51 47

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        final MainSoundPlayer mainSoundPlayer = new MainSoundPlayer(this);
        getLifecycle().addObserver(mainSoundPlayer);

        findViewById(R.id.start_btn).setOnClickListener(v -> {
            mainSoundPlayer.playClappingSound();
        });
        findViewById(R.id.stop_btn).setOnClickListener(v -> {
            mainSoundPlayer.stopClappingSound();
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        // ここで自動的に停止した効果音が再開される
    }

    @Override
    protected void onPause() {
        super.onPause();
        // ここで自動的に効果音が停止される
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/start_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="START" />

    <Button
        android:id="@+id/stop_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="STOP" />
</LinearLayout>

capture API 30 (OS 11)

STARTボタンを押したら効果音が再生される
STOPボタンを押したら効果音が停止される

device-2023-10-03-180056.webm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment