MediaPlayer Demo 开发记录
这个记录主要针对的是多媒体下的audio的练习——对于音乐🎵的基本操作:播放,暂停,重播!play,pause,restart;按照以上的思路,构建一个demo专门实现这三个功能!
ui设计
每一个功能对应一个按钮button实现;在ui设计上就得只是设计三个对应的按钮!
代码基本如下:我添加一个Image,起码让它看起来没那么简陋罢了;
<?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">
<ImageView
android:id="@+id/image_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/enjoy_music"
app:layout_constraintBottom_toTopOf="@id/LinearLayout_1"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<LinearLayout
android:id="@+id/LinearLayout_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/image_view"
app:layout_constraintBottom_toBottomOf="parent"
>
<Button
android:id="@+id/button_play"
android:layout_weight="1"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="play"/>
<Button
android:id="@+id/button_pause"
android:layout_weight="1"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="pause"/>
<Button
android:id="@+id/button_stop"
android:layout_weight="1"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stop"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
业务逻辑
这个是最关键的,基本的思路就是对于这个media进行控制;不过在这里要也特别注意线程的因素,毕竟一个音视频也不算小,占据线程很容易导致崩溃的。在官方文档中也提及过这一点!还是需要好好研究!!!如何控制线程奔溃出现??
音乐播放如果是读取手机中的文件是需要相应的权限的!
状态图很重要‼️‼️
在编写代码的时候,出现的一个bug就是:
com.example.mediaplayerpractice_1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mediaplayerpractice_1, PID: 16223
java.lang.IllegalStateException:
这个问题的出现主要是我没按照正确的状态图,直接就从一个状态飞到另外一个状态!人家是质的飞跃,我是容易扯到egg的操作!还是要按照状态图中的各个状态进行分析和编写就不太容易出现大的问题。
修改后的正确代码:
package com.example.mediaplayerpractice_1;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import android.widget.Toolbar;
import java.io.File;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//MediaPlayer
private MediaPlayer mediaplayer = new MediaPlayer();
//Ui
private Button buttonPlay;
private Button buttonPause;
private Button buttonStop;
//动态申请权限;
private static String[] PERMISSIONS = {
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE"
};
static boolean FLAG_PERMISSIONS = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initUI();
if(!FLAG_PERMISSIONS){// 权限没有获取的时候就检查权限
checkPermission();
}
mediaplayer = MediaPlayer.create(getApplicationContext(),R.raw.music);
mediaplayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
initMusicPlayer();
}
});
mediaplayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
}
});
}
private void checkPermission() {
//进行权限查询,这个和之前的ContentProvider中的权限申请,很像,可参考!
for(String permission : PERMISSIONS){
if(ContextCompat.checkSelfPermission(MainActivity.this,permission) != PackageManager.PERMISSION_GRANTED ){
//审查权限
ActivityCompat.requestPermissions(this,PERMISSIONS,1);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
for (int grantResult : grantResults){
if(grantResult != PackageManager.PERMISSION_GRANTED){
FLAG_PERMISSIONS = false;
Toast.makeText(getApplicationContext(),"Permisson is denied!",Toast.LENGTH_SHORT).show();
break;
}
}
FLAG_PERMISSIONS = true;
break;
}
}
private void initMusicPlayer() {
// File file = new File(Environment.getExternalStorageDirectory(),"music.mp3");//这个是读取外部中的文件(即手机中文件)
try {
// mediaplayer.setDataSource(file.getAbsolutePath());
mediaplayer = MediaPlayer.create(getApplicationContext(),R.raw.music);//这段代码主要体现的是在IDE中直接读取自带的文件,它直接调用prepare方法
// mediaplayer.prepare();//准备媒体
} catch (Exception e ) {
e.printStackTrace();
Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
private void initUI() {
buttonPlay = findViewById(R.id.button_play);
buttonPause = findViewById(R.id.button_pause);
buttonStop = findViewById(R.id.button_stop);
buttonPause.setOnClickListener(this);
buttonStop.setOnClickListener(this);
buttonPlay.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_play:
if(!mediaplayer.isPlaying()){
mediaplayer.start();
Toast.makeText(getApplicationContext(),"Playing",Toast.LENGTH_SHORT).show();
}
break;
case R.id.button_pause:
if(mediaplayer.isPlaying()){
mediaplayer.pause();
Toast.makeText(getApplicationContext(),"Pausing",Toast.LENGTH_SHORT).show();
}
break;
case R.id.button_stop:
if (mediaplayer.isPlaying()){
mediaplayer.stop();
Toast.makeText(getApplicationContext(),"Stopping",Toast.LENGTH_SHORT).show();
initMusicPlayer();
}
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mediaplayer != null){
mediaplayer.stop();
mediaplayer.release();
}
}
}