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 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"><Buttonandroid:id="@+id/button_start"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="START"/><Buttonandroid:id="@+id/button_pause"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="PAUSE"/><Buttonandroid:id="@+id/button_stop"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="STOP"/><SeekBarandroid:id="@+id/seekbar"android:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout>部分Java代码如下,重点在于进度条监听器的逻辑处理代码,runnable的逻辑处理代码,按钮监听器的逻辑处理代码。
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;@Overrideprotected 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() {@Overridepublic void onProgressChanged(SeekBar seekBar, int i, boolean b) {Log.d(TAG, "onProgressChanged: ");}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {Log.d(TAG, "onStartTrackingTouch: ");if_seek = true;}@Overridepublic 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() {@Overridepublic 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);}@Overridepublic 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();}}@Overrideprotected 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 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"><Buttonandroid:id="@+id/button_start"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="START" /><Buttonandroid:id="@+id/button_pause"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="PAUSE" /><Buttonandroid:id="@+id/button_stop"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="STOP" /><SurfaceViewandroid:id="@+id/surfaceView"android:layout_width="match_parent"android:layout_height="250dp"android:layout_marginTop="10dp"android:layout_gravity="center"/></LinearLayout>部分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;@Overrideprotected 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);}@Overridepublic 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();}}@Overridepublic void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {mediaPlayer_surface = MediaPlayer.create(this, R.raw.hby);mediaPlayer_surface.setDisplay(surfaceHolder);}@Overridepublic void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {}@Overridepublic void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {}
}效果图如下。

