MediaPlayer类是Androd多媒体框架中的一个重要的组件,通过该类,我们可以获取并播放音视频。
对播放器的主要控制方法:
Android通过控制播放器的状态的方式来控制媒体文件的播放,其中:
prepare()和prepareAsync() 提供了同步和异步两种方式设置播放器进入prepare状态,需要注意的是,如果MediaPlayer实例是由create方法创建的,那么第一次启动播放前不需要再调用prepare()了,因为create方法里已经调用过了。
start()是真正启动文件播放的方法,
pause()和stop()比较简单,起到暂停和停止播放的作用,
seekTo()是定位方法,可以让播放器从指定的位置开始播放,需要注意的是该方法是个异步方法,也就是说该方法返回时并不意味着定位完成,尤其是播放的网络文件,真正定位完成时会触发OnSeekComplete.onSeekComplete(),如果需要是可以调用setOnSeekCompleteListener(OnSeekCompleteListener)设置监听器来处理的。
release()可以释放播放器占用的资源,一旦确定不再使用播放器时应当尽早调用它释放资源。
reset()可以使播放器从Error状态中恢复过来,重新会到Idle状态。
它支持三种不同的媒体来源:
本地资源
内部URI,比如你可以通过ContentResolver来获取
外部URL(流)
本地资源的获取则是将音频文件放在一个自己在res下面创建的raw文件中:
MediaPlayer mp = MediaPlayer.create(this, R.raw.test);
内部URI,
可以直接写上音频在sd卡的路径(前提是知道文件位置)
这里就直接写通过ContentResolver来获取SD卡中的所有歌曲文件了:
Cursor cursor=contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,null);
while (cursor.moveToNext()){
//音乐id
Long ID=cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID));
//音乐标题
String TITLE=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
//艺术家
String ARTIST=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
//专辑
String ALBUM=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
//专辑id
Long ALBUM_ID=cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
//时长
Long DURATION=cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
//文件大小
Long SIZE=cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE));
//文件路径
String DATA=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
//是否为音乐
Long IS_MUSIC=cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));
}
用以上这段代码来获取手机中的MP3歌曲的路径
MediaPlayer mediaPlayer=new MediaPlayer();
mediaPlayer.setDataSource(this, Uri.parse("file://"+DATA));
//播放前准备一下
mediaPlayer.prepare();
//监听:准备完成的监听
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
使用前要获取访问sd卡的权限
在AndroidManifest直接用以下的代码
//获取访问网络权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
//获取访问sd卡权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
在SDK6.0会遇到一个这样的问题:requires Android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
原因:从6.0(api 23)开始, android采用了Runtime permission request, 即在运行时请求权限,而不是在编译的时候,即使在manifest.xml里面添加了权限也要在运行时请求。
但不是所有的permission都要Runtime request,涉及到资源文件请求时就会用到Runtime request,比如获取位置信息, content provider获取media的情况。
解决方法:
//运行时调用
@SuppressLint("NewApi")
private void requestReadExternalPermission() {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
} else {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
}
} else {
}
}
//处理请求:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 0: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
}
return;
}
default:
break;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
外部URL(流):
MediaPlayer mediaPlayer=new MediaPlayer();
//和内部uri唯一区别就是这一段,其他一样
mediaPlayer.setDataSource(this, Uri.parse("http://192.168.43.135/internet.mp3"));
//异步
mediaPlayer.prepareAsync();