Android Studio新手开发第三十一天

利用MediaPlayer播放音频

MediaPlayer 是 Android 系统中用于播放音频和视频文件的核心组件,它提供了一套完整的API,能够以较小的代价处理多媒体播放任务。它常用的方法说明如下:

1.reset:重置播放器。

2.prepare:准备播放。

3.start:开始播放。

4.pause:暂停播放。

5.create:创建指定Uri或者资源编号的播放器。

6.setDateSource:设置播放器数据来源的文件路径,它与create只需调用一次即可。

7.setVolume:设置音量。它有两个参数,分别是左右声道的音量,取值范围0~1。

8.setAudioStreamType:设置音频流的类型。

9.setLooping:设置是否循环播放,true为循环播放,false为播放一次。

10.isPlaying:判断是否正在播放。

11.getCurrentPosition:获取当前播放进度所在位置。

12.getDuration:获取播放时长,单位为毫秒。

下面以播放音频为例,现在res/raw目录下添加一个音频文件,没有raw目录可以自行新建一个。示例代码如下,在布局文件中添加了三个按钮已经一个进度条。

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MultiMedia.MediaPlayerActivity"
    android:orientation="vertical">

    <Button
        android:id="@+id/button_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="START"/>
    <Button
        android:id="@+id/button_pause"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="PAUSE"/>
    <Button
        android:id="@+id/button_stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="STOP"/>

    <SeekBar
        android:id="@+id/seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

部分Java代码如下,重点在于进度条监听器的逻辑处理代码,runnable的逻辑处理代码,按钮监听器的逻辑处理代码。

java 复制代码
public class MediaPlayerActivity extends AppCompatActivity implements View.OnClickListener {
    private Button button_start, button_pause, button_stop;
    private SeekBar seekbar;
    private MediaPlayer mediaPlayer;
    private boolean if_seek = false;
    private Time time;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_player);
        button_start = findViewById(R.id.button_start);
        button_pause = findViewById(R.id.button_pause);
        button_stop = findViewById(R.id.button_stop);
        seekbar = findViewById(R.id.seekbar);
        button_start.setOnClickListener(this);
        button_pause.setOnClickListener(this);
        button_stop.setOnClickListener(this);
        seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                Log.d(TAG, "onProgressChanged: ");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Log.d(TAG, "onStartTrackingTouch: ");
                if_seek = true;
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Log.d(TAG, "onStopTrackingTouch: ");
                if (mediaPlayer != null) {
                    mediaPlayer.seekTo(seekBar.getProgress());
                }
                if_seek = false;
            }
        });

    }

    private Handler mHandler = new Handler();
    private Runnable mUpdateProgressRunnable = new Runnable() {
        @Override
        public void run() {
            if (mediaPlayer != null && !if_seek) { // 用户未拖动时才更新
                int currentPosition = mediaPlayer.getCurrentPosition(); // 获取当前播放位置[citation:5]
                seekbar.setProgress(currentPosition); // 更新SeekBar进度[citation:5]
                Log.d(TAG, "run: ");
            }
            //音乐播放结束,停止更新进度条,进度条重置
            if (mediaPlayer.getDuration() == seekbar.getProgress()){
                mHandler.removeCallbacks(mUpdateProgressRunnable);
                seekbar.setProgress(0);
            }
            // 每隔一定时间(如500毫秒)更新一次
            mHandler.postDelayed(this, 1000);
        }
    };

    // 开始更新进度
    private void startProgressUpdate() {
        mHandler.post(mUpdateProgressRunnable);
    }

    // 停止更新进度
    private void stopProgressUpdate() {
        mHandler.removeCallbacks(mUpdateProgressRunnable);
        mediaPlayer = null;
        seekbar.setMax(0);
    }

    //暂停更新进度
    private void pauseProgressUpdate() {
        mHandler.removeCallbacks(mUpdateProgressRunnable);
    }


    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.button_start) {
            if (mediaPlayer == null){
                mediaPlayer = MediaPlayer.create(this, R.raw.hsf);
                seekbar.setMax(mediaPlayer.getDuration());
            }
            if (!mediaPlayer.isPlaying()) {
                mediaPlayer.start();
                Log.d(TAG, "START");
            }
            startProgressUpdate();

        } else if (view.getId() == R.id.button_pause) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                Log.d(TAG, "PAUSE");
            }
            if (mediaPlayer == null){return;}
            pauseProgressUpdate();

        }else if (view.getId() == R.id.button_stop){
            mediaPlayer.stop();
            stopProgressUpdate();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mediaPlayer.release();
        mediaPlayer = null;
    }
}

效果图如下,点击对应的按钮实现音频的开始,暂停以及结束,点击进度条跳转至对应播放位置。注意在调用MediaPlayer的stop方法后若要开始音频则需要重新设置MediaPlayer的数据源。在退出APP时建议在onDestroy方法或者onStop方法上调用MediaPlayer的release方法释放系统资源或者在不使用MediaPlayer时调用该方法以减少系统资源占用。

利用MediaPlayer播放视频

MediaPlayer除了可以用来播放音频,它也可以用来播放视频,不过它还需要配合其他视图来展示视频。利用MediaPlayer播放音频可以知道它是没有在页面上显示的,只有通过其他视图来控制播放等操作。而MediaPlayer播放视频就需要一个能够承载视频的视图SurfaceView。一般情况下可以使用视图VideoView直接展示视频,不过这种方式占用系统资源较大。利用MediaPlayer结合SurfaceView可以减少系统资源占用。示例代码如下,

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MultiMedia.MediaPlayerActivity">

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

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

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


    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:layout_marginTop="10dp"
        android:layout_gravity="center"/>

</LinearLayout>

部分Java代码如下。

java 复制代码
public class MediaPlayerActivity extends AppCompatActivity implements View.OnClickListener, SurfaceHolder.Callback {
    private Button button_start, button_pause, button_stop;
    private SurfaceView surfaceView;
    private MediaPlayer  mediaPlayer_surface;
    private SurfaceHolder surfaceHolder;

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

        button_start = findViewById(R.id.button_start);
        button_pause = findViewById(R.id.button_pause);
        button_stop = findViewById(R.id.button_stop);
        surfaceView = findViewById(R.id.surfaceView);

        button_start.setOnClickListener(this);
        button_pause.setOnClickListener(this);
        button_stop.setOnClickListener(this);

        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
    }


    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.button_start) {

            mediaPlayer_surface.start();

        } else if (view.getId() == R.id.button_pause) {

            mediaPlayer_surface.pause();
        } else if (view.getId() == R.id.button_stop) {
            mediaPlayer_surface.stop();
        }
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
        mediaPlayer_surface = MediaPlayer.create(this, R.raw.hby);
        mediaPlayer_surface.setDisplay(surfaceHolder);
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
    }
}

效果图如下。

相关推荐
圆粥綠21 小时前
【保姆级】国内Windows用户Android Studio下载+安装+配置完整教程(2026最新版,避坑指南)
android·windows·android studio
大貔貅喝啤酒3 天前
基于Windows下载安装Android Studio 3.3.2版本教程(2026详细图文版)
android·java·windows·android studio
我命由我123453 天前
Android 开发问题:TextView 内容超过宽度时,默认不会换行
android·开发语言·java-ee·android studio·android jetpack·android-studio·android runtime
BoomHe4 天前
git Rebase 为任意一笔提交补上 Change-Id
android·git·android studio
黄林晴4 天前
Google I/O 2026 Android开发者速览
android·android studio
真鬼1234 天前
【Unity安卓】Unity 嵌入 Android Studio 完整流程
android·unity·android studio
liguojun20254 天前
软硬一体智慧场馆系统推荐——助力场馆数字化高效升级
java·大数据·人工智能·物联网·1024程序员节
子非吾喵4 天前
HBuilder X本地打包的资源放到Android Studio本地打包的记录
android·ide·android studio
李斯维5 天前
Jetpack 生命周期组件 Lifecycle 的设计思想和使用
android·android studio·android jetpack