Detailed steps for Android SoundPool to play sound effects

Although MediaPlayer can also play audio, it has the disadvantages of high resource usage, long delay time, and does not support multiple audio playback at the same time . Scenes that require relatively high time accuracy, and SoundPoo is generally used to play dense, rapid and short-lived sound effects, such as: "Let's go right away with a drop"

1. Add permissions:

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

2. Dynamically add permissions

ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO},
                100);

3. Create a SoundActivity and use Intent to connect MainActivity and SoundActivity

Full code:

MainActivity layout file activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
	 <Button
        android:onClick="playAudio"
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="播放音效"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button2" />
    
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**
         * 在 Android 6.0 以上需要动态添加权限
         */
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO},
                100);

    }

    /**
     * 播放音效
     * @param view
     */
    public void playAudio(View view) {
        //跳转到SoundActivity完成播放音效
        startActivity(new Intent(this, SoundActivity.class));
    }
}

SoundActivity.java layout file activity_sound.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Adapter file MyAdapter.java

package com.example.mediademo;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements View.OnClickListener {

    //条目数据
    private final List<SoundActivity.Sound> data;
    private final Context context;
    private final RecyclerView recyclerView;
    private OnItemClickListener listener;

    //构造方法
    public MyAdapter(List<SoundActivity.Sound> data, RecyclerView recyclerView, Context context) {
        this.data = data;
        this.recyclerView = recyclerView;
        this.context = context;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //定义TextView显示文本 (a4/a5/a6...)
        TextView textView = new TextView(context);
        //设置布局宽高
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.topMargin = 18;
        layoutParams.leftMargin = 18;
        textView.setLayoutParams(layoutParams);
        //文本字体大小
        textView.setTextSize(20);
        //设置TextView的点击事件
        textView.setOnClickListener(this);
        return new MyViewHolder(textView);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        //拿到外面传递进来的data数据,拿到name值赋值给TextView
        ((TextView) holder.itemView).setText(data.get(position).getName());
    }

    /**
     * 条目个数
     * @return
     */
    @Override
    public int getItemCount() {
        return data.size();
    }

    /**
     * 点击事件
     * @param v
     */
    @Override
    public void onClick(View v) {
        if (listener != null) {
            listener.onItemClick(recyclerView.getChildAdapterPosition(v));
        }
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        this.listener = listener;
    }

    interface OnItemClickListener {
        void onItemClick(int position);
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
        }
    }
}

SoundActivity.java

package com.example.mediademo;
import android.media.SoundPool;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

public class SoundActivity extends AppCompatActivity implements MyAdapter.OnItemClickListener {

    //soundPool示例对象
    private SoundPool soundPool;

    //封装bean
    static class Sound {
        String name;
        int soundId;

        public Sound(String name, int soundId) {
            this.name = name;
            this.soundId = soundId;
        }

        public int getSoundId() {
            return soundId;
        }

        public String getName() {
            return name;
        }
    }

    //条目
    List<Sound> data;

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

        //获取RecyclerView
        RecyclerView recyclerView = findViewById(R.id.recyclerView);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);

        //创建soundPool示例对象 setMaxStreams(6)有6个音频
        soundPool = new SoundPool.Builder().setMaxStreams(6).build();

        //加载播放音效 给条目塞值(本地文件:res--》raw--》a4.mp3)
        data = new ArrayList<>();
        data.add(new Sound("a4", soundPool.load(this, R.raw.a4, 1)));
        data.add(new Sound("a5", soundPool.load(this, R.raw.a5, 1)));
        data.add(new Sound("a6", soundPool.load(this, R.raw.a6, 1)));
        data.add(new Sound("a7", soundPool.load(this, R.raw.a7, 1)));
        data.add(new Sound("a8", soundPool.load(this, R.raw.a8, 1)));
        data.add(new Sound("a9", soundPool.load(this, R.raw.a9, 1)));
        //适配
        MyAdapter myAdapter = new MyAdapter(data, recyclerView, this);
        //点击事件
        myAdapter.setOnItemClickListener(this);
        //传递给RecyclerView
        recyclerView.setAdapter(myAdapter);

    }

    //点击事件(播放)
    @Override
    public void onItemClick(int position) {
        //拿到当前点击的音频
        Sound sound = data.get(position);
        //播放(参数一:SoundId | 参数二、三:音量 | 参数四:优先级 | 参数五:循环 0:不循环 1:循环2次 | 参数六:播放速度1.0正常速度)
        soundPool.play(sound.getSoundId(),
                1.0f, 1.0f, 1, 0, 1.0f);
    }

    //播放完毕(释放)
    @Override
    protected void onDestroy() {
        super.onDestroy();
        for (Sound datum : data) {
            //把音效卸载
            soundPool.unload(datum.getSoundId());
        }
        //释放soundPool
        soundPool.release();
    }
}

A simple and playable sound effect of the sound effect material is enough (,mp3/.mp4)

It is recommended to use the real device test

Guess you like

Origin blog.csdn.net/weixin_53443677/article/details/126470018