应当随时学习,学习一切;应当集中全力,以求知道更多,知道一切。
目录结构
- 1. 前言
- 2. MediaPlayer介绍
- 3. MediaPlayer 实战
- 3.1 简易音频播放器
- 第一步:布局设置
- 第二步:实现逻辑
- 第三步:申请权限
- 3.2 简易音频播放器
- 第一步:设置布局
- 第二步:实现逻辑
- 4. 简易音频播放器Demo
1. 前言
最近在学习 Android多媒体方面的知识,为此进行了整理,作为自己的学习输出。本篇主要分享Android中Mediaplayer
API 方面的知识点,以及 demo——简易音频播放器。在demo中会分享两个demo,一个是包含播放、暂停、停止按钮的简易音频播放器,另一个demo中带有SeekBar
的音频播放器。
2. MediaPlayer介绍
- 简介
MediaPlayer
类主要用于控制音频/视频文件和流的播放。在该类中提供了很多控制音视频的方法,可在官网中进行查看MediaPlayer - 支持的媒体格式
支持的格式: .mp3、.mp4 、.3gp、.ave等 - 经典状态图 (from 官网)
MediaPlayer类的官网文档展示了一个非常完整的状态图,该图说明了哪些方法可将一种状态变为另一种状态。 - 上述状态图主要展示了MediaPlayer 对象的生命周期和状态,椭圆形代表 MediaPlayer对象当前的状态。单箭头主要是方法调用的方向。
MediaPlayer
对象的生命周期
:
从Idle
状态——到End
状态
当MediaPlayer对象被创建或者被调用reset()
方法后,MediaPlayer对象处于idle状态
。
当被调用release()
方法后,MediaPlayer对象处于End状态
- 状态描述:
当MediaPlayer对象处于idle状态
时,此时可以调用setDataSource()
初始化该类,使其处于initialized状态
,然后必须使用prepare()
或者prepareAsync()
方法完成准备工作。当MediaPlayer对象准备就绪后,它就会进入prepared状态
,此时,就可以调用start()
、pause()
、stop()
来操作音频。当MediaPlayer对象为stoped状态
时,除非再次准备MediaPlayer,否则将无法再次调用start()
。
3. MediaPlayer 实战
MediaPlayer
类实现音频播放器的步骤如下:
3.1 简易音频播放器
第一步:布局设置
设置三个Button分别用于控制音频的播放、暂停和停止。
<?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=".MainActivity"
android:orientation="vertical">
<Button
android:id="@+id/btn_play"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Play" />
<Button
android:id="@+id/btn_pause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pause" />
<Button
android:id="@+id/btn_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop" />
</LinearLayout>
第二步:实现逻辑
- 获取Button对象,此处是
实现View.OnClickListener()
来重写onClick()
。 - 在
create()
中处理动态获取权限,因为要访问SD卡,所以要有WRITE_EXTERNAL_STORAGE权限
。如果没有动态申请的话,则需要手动打开应用的存储权限。 - 写一个方法
initMediaPlayer()
主要是为MediaPlayer对象进行初始化操作。 - 在
onClick()
中对音频进行操作。 - 在
onDestroy()
中,释放资源。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button play, pause, stop;
private MediaPlayer mediaPlayer = new MediaPlayer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取button对象
play = findViewById(R.id.btn_play);
pause = findViewById(R.id.btn_pause);
stop = findViewById(R.id.btn_stop);
//实现点击事件监听器(View.OnClickListener)
play.setOnClickListener(this);
pause.setOnClickListener(this);
stop.setOnClickListener(this);
//***********动态获取权限*****************
if(ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE },1);
}else{
//初始化 MediaPlayer
//initMediaPlayer();
}
//initMediaPlayer();
}
//初始化MediaPlayer对象
private void initMediaPlayer() {
try {
File file = new File(Environment.getExternalStorageDirectory(), "/testmusic.mp3");
mediaPlayer.setDataSource(file.getPath()); // 指定音频文件的路径
mediaPlayer.prepare(); // 让Mediaplayer 进入到准备状态
} catch (Exception e) {
e.printStackTrace();
}
}
//********* 如果用户拒绝了权限申请,那么就需要调用finish()方法将程序直接关掉
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
initMediaPlayer();
}else {
Toast.makeText(this,"拒绝权限将无法使用程序",Toast.LENGTH_SHORT).show();
finish();
}
break;
default:
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_play:
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
break;
case R.id.btn_pause:
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
break;
case R.id.btn_stop:
if (mediaPlayer.isPlaying()) {
mediaPlayer.reset();//停止播放
initMediaPlayer();
}
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
}
}
}
第三步:申请权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
赶快运行下你的 Demo 吧!
3.2 简易音频播放器
使用MediaPlayer+SeekBar
,申请权限步骤同上,使用MediaPlayer.create()
加载音频文件时,需要在res目录下,新建一个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=".MainActivity"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<Button
android:id="@+id/btn_play"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Play" />
<Button
android:id="@+id/btn_pause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pause" />
<Button
android:id="@+id/btn_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop" />
</LinearLayout>
<SeekBar
android:id="@+id/btn_seekto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
第二步:实现逻辑
在资源加载这块使用 MediaPlayer.create()
package com.xiaozeng.mediaplayerdemo3;
....
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private MediaPlayer mediaPlayer ;
private SeekBar seekBar;
private SeekBar seek;
Button play;
Button pause;
Button stop;
private Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(msg.what == 0){
int mediaProcess = mediaPlayer.getCurrentPosition();
seek.setProgress(mediaProcess);
handler.sendEmptyMessageDelayed(0,1000);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取button对象
play = findViewById(R.id.btn_play);
pause = findViewById(R.id.btn_pause);
stop = findViewById(R.id.btn_stop);
seek = findViewById(R.id.btn_seekto);
play.setOnClickListener(this);
pause.setOnClickListener(this);
stop.setOnClickListener(this);
mediaPlayer = MediaPlayer.create(this,R.raw.testmusic);
seek.setMax(mediaPlayer.getDuration());
seek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
int seekProcess = seekBar.getProgress();
mediaPlayer.seekTo(seekProcess);
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_play:
if(mediaPlayer !=null && !mediaPlayer.isPlaying() ){
mediaPlayer.start();
handler.sendEmptyMessageDelayed(0,1000);
}
break;
case R.id.btn_pause:
if(mediaPlayer !=null && mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
break;
case R.id.btn_stop:
if (mediaPlayer !=null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
// mediaPlayer.reset();
try {
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
}
}
}
4. 简易音频播放器Demo
快运行下你的Demo吧!
行文仓促,认识有限,欢迎讨论拍砖啊