1.播放本地音乐:mediaPlayer.setDataSource(文件路径);
2.播放网络音乐:mediaPlayer.setDataSource(“http://www.ytmp3.cn/down/57799.mp3”);
3.完成音乐列表,实现播放/暂停/上一首/下一首/播放模式切换(随机播放/单曲循环/顺序播放)
详细说明:https://www.jianshu.com/p/0131ab02e0fe
注意:reset方法是将数据清空。 release方法是将媒体对象回收掉
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(path);
// 通过异步的方式装载媒体资源
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// 装载完毕回调
mediaPlayer.start();
}
});
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
// 设置循环播放
// mediaPlayer.setLooping(true);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// 在播放完毕被回调
play();
}
});
(0)在Activity中主动获取权限:
在安卓6.0以后除了需要在manifest文件中注册各权限外,还需要在代码中动态调用安卓API申请权限。
public class MediaActivity extends AppCompatActivity {
private ViewPager viewPager;
private TabLayout tabLayout;
private ArrayList<Fragment> list=new ArrayList<>();
private MyFragmentPagerAdapter myFragmentPagerAdapter;
//列出需要主动获取的权限WRITE_EXTERNAL_STORAGE/READ_EXTERNAL_STORAGE读写SD卡权限
private String[] permissiones=new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media);
initView();//初始化布局 ViewPager_TabLayout_Fragent
checkPermission();//检测这些权限是否已经申请过
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void checkPermission(){
int readCode = ActivityCompat.checkSelfPermission(this,permissiones[0]);
int writeCode = ActivityCompat.checkSelfPermission(this,permissiones[1]);
if (!(readCode== PackageManager.PERMISSION_GRANTED)||!(writeCode==PackageManager.PERMISSION_GRANTED)){//只要有一项没有申请到
//主动去申请权限
requestPermissions(permissiones,100);//要动态申请的权限;100请求状态码->判断哪次动态申请的
}
}
//动态权限申请回调方法->获取动态申请结果
//permissions->动态申请的权限
//grantResults->动态权限申请结果->若干结果中1个权限申请失败->申请失败
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (100==requestCode){
boolean flag = true;
//遍历请求结果数组->若有一个权限失败->flag=false->本次申请失败
for (int code : grantResults){
if (code!=PackageManager.PERMISSION_GRANTED) {
flag = false;
break;
}
}
if (flag)
Toast.makeText(this,"申请成功",Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"申请失败",Toast.LENGTH_SHORT).show();
}
}
private void initView() {
viewPager=findViewById(R.id.vp);
tabLayout=findViewById(R.id.tab);
list.add(new Fragment_one());
list.add(new Fragment_two());
myFragmentPagerAdapter=new MyFragmentPagerAdapter(getSupportFragmentManager(),list);
viewPager.setAdapter(myFragmentPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
}
(1)Music实体类:
public class Music implements Serializable{
private String name;
private String singer;
private long duration;
private String data;
public Music(String name, String singer, long duration, String data) {
this.name = name;
this.singer = singer;
this.duration = duration;
this.data = data;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
(3)使用内容提供者获得音频资料并展现在RecyclerView列表中
public class Fragment_one extends Fragment implements BaseRecyclerViewAdapter.OnItemClick {
private ContentResolver contentResolver;//内容解析者
private Uri uri;//uri
private String[] strs;//要查询到字段
private ArrayList<Music> list=new ArrayList<>();
private RecyclerView rv;
private BaseRecyclerViewAdapter<Music> adapter;//万能适配器
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, null);
rv=view.findViewById(R.id.music_rv);
initdata();//获取数据
return view;
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
private void initdata() {
contentResolver= getActivity().getContentResolver();//获得解析者
uri= MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;//确定Uri
//TITLE:歌名 DATA:文件路径 DURATION:总时长,毫秒值为单位 ARTIST:歌手名称
strs=new String[]{MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST};
Cursor cursor = contentResolver.query(uri, strs,null,null,null,null);
while (cursor.moveToNext()){
list.add(new Music(cursor.getString(0),cursor.getString(3),cursor.getLong(2),cursor.getString(1)));
}
//万能适配
adapter=new BaseRecyclerViewAdapter<Music>(R.layout.item_one,getActivity(),list) {
@Override
public void bind(BaseViewHolder holder, int position) {
holder.setText(R.id.tv_singer,list.get(position).getSinger());
holder.setText(R.id.tv_title,list.get(position).getName());
}
};
rv.setAdapter(adapter);
rv.setLayoutManager(new LinearLayoutManager(getContext()));
adapter.setClick(this);//设置点击事件
}
private MediaPlayer mediaPlayer;
@Override
public void ItemClick(int index) {
Intent intent = new Intent(getActivity(),MusicActivity.class);
intent.putExtra("music",list.get(index));
startActivity(intent);
}
}
(4)点击列表中的一项播放音乐
public class MusicActivity extends AppCompatActivity implements View.OnClickListener,SeekBar.OnSeekBarChangeListener {
private SeekBar seekBar;
private Button paly,pause,stop,pre,next;
private SingleMediaPlayer mediaPlayer;
private Music music;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music);
initView();
initData();
}
private void initData() {
seekBar.setMax((int) music.getDuration());//设置进度条的最大值为音乐的时长
music = (Music) getIntent().getSerializableExtra("music");//音乐对象
if(mediaPlayer==null){
mediaPlayer=SingleMediaPlayer.getMediaPlayer();//单粒模式的mediaPlayer对象
}
try {
mediaPlayer.reset();//重置数据
mediaPlayer.setDataSource(music.getData());//设置新的数据源
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {//设置准备播放音乐
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();//开始播放音乐
}
});
} catch (IOException e) {
e.printStackTrace();
}
//定时器更新进度条
Timer timer=new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
});
}
},0,1000);
}
private void initView() {
seekBar=findViewById(R.id.seekbar);
paly=findViewById(R.id.play);
pause=findViewById(R.id.pause);
stop=findViewById(R.id.stop);
pre=findViewById(R.id.pre);
next=findViewById(R.id.next);
paly.setOnClickListener(this);
pause.setOnClickListener(this);
stop.setOnClickListener(this);
pre.setOnClickListener(this);
next.setOnClickListener(this);
seekBar.setOnSeekBarChangeListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.play:
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
}
break;
case R.id.pause:
if(mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
break;
case R.id.pre:
break;
case R.id.next:
break;
case R.id.stop:
mediaPlayer.stop();
break;
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(b){//判断是否来自用户的拖动
mediaPlayer.seekTo(i);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}