无聊做了一个本地音乐播放器,功能有:获取本地的音乐文件,对音乐进行播放,可以上一首,下一首,列表循环播放,单曲循环播放,随机播放。
页面很简单,只有两个页面页面如图所示:
视频预览:
主要代码讲解:
权限申请
在清单文件中加入权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
然后发起权限申请
//请求权限
requestPermissions(new String[]{
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_EXTERNAL_STORAGE,
},0);
权限申请结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean grant=true;
if (requestCode==0){
for (Integer integer:grantResults){
if (integer != 0) {
grant = false;
break;
}
}
//权限给了,就获取音乐
if (grant){
getMusic();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
获取本地音乐
//使用ContentResolver获取音乐
private void getMusic(){
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
if (cursor!=null){
while (cursor.moveToNext()){
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String data = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
String duration = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
if (duration==null)continue;
if (Integer.parseInt(duration)>5000){
int i = Integer.parseInt(duration);
String time = String.format(getString(R.string.s_s), format(i / 1000 / 60), format(i / 1000 % 60));
Music music = new Music(title, artist, data, time,i);
musicList.add(music);
}
musicAdapter.notifyDataSetChanged();
App.getService().setMusicList(musicList);
}
cursor.close();
}
}
设置音乐信息
private void setMusic(Music music){
//设置音乐名
title.setText(music.getTitle());
cover.setImageResource(R.drawable.music);
//显示音乐进度条时长
end.setText(music.getTime());
//设置进度条总时长
seekBar.setMax(music.getDuration()/1000);
//进度条拖动监听
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser&&App.getService().isPlaying()) {
App.getService().seekTo(progress*1000);
start.setText(String.format(getString(R.string.s_s), format(progress / 60), format(progress % 60)));
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 不需要处理
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (!App.getService().isPlaying()){
start.setText(R.string._00_00);
seekBar.setProgress(0);
}
}
});
}
更新进度条
//更新进度条
private void updateSeekBar() {
runnable = new Runnable() {
@Override
public void run() {
if (App.getService() != null&&App.getService().isPlaying()) {
rotationAnimator.resume();
btn_play.setImageResource(R.drawable.ic_play_btn_pause);
int currentPosition = App.getService().getNow();
seekBar.setProgress(currentPosition/1000);
start.setText(String.format(getString(R.string.s_s), format(currentPosition / 1000 / 60), format(currentPosition / 1000 % 60)));
}
else {
rotationAnimator.pause();
btn_play.setImageResource(R.drawable.ic_play_btn_play);
}
handler.postDelayed(this, 1000); // 每秒更新一次进度条
}
};
handler.postDelayed(runnable, 0);
}
Music实体类
public class Music implements Serializable {
private String title,artist,data, time;
private int duration;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public Music(String title, String artist, String data, String time, int duration) {
this.title = title;
this.artist = artist;
this.data = data;
this.time = time;
this.duration = duration;
}
}
音乐播放服务
public class MusicService extends Service implements MediaPlayer.OnCompletionListener{
private final IBinder binder = new MusicBinder();
private MediaPlayer mediaPlayer;
private List<Music> musicList=new ArrayList<>();
private int position;
private int status=0;
private Music music;
private Random random = new Random();
private int lowerBound = 0; // 最小值
private int upperBound = 0; // 最大值
public MusicService() {
}
@Override
public void onCreate() {
super.onCreate();
if (mediaPlayer==null){
mediaPlayer=new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
}
}
//判断是否正在播放
public boolean isPlaying(){
return mediaPlayer.isPlaying();
}
//设置音乐
public void setMusic(Music music){
if (music!=null){
this.music=music;
RxBus.getDefault().removeAllStickyEvents();
RxBus.getDefault().postSticky(music);
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(music.getData());
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public Music getMusic(int position){
if (position>=0&&position<musicList.size()){
return musicList.get(position);
}
return null;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public void setData(int position){
this.position = position;
if (position>=0&&position<musicList.size()){
setMusic(musicList.get(position));
}
}
public void setMusicList(List<Music> musicList) {
this.musicList = musicList;
upperBound=musicList.size()-1;
}
//上一首
public void pre(){
if (status==1){
randomPlay();
}
else {
position=(position-1) % musicList.size();
if (position<0){
position=musicList.size()-1;
}
Music music = musicList.get(position);
if (music!=null){
setMusic(music);
playOrPause();
}
}
}
//下一首
public void next(){
if (status==1){
randomPlay();
}
else {
position=(position+1) % (musicList.size());
Music music = musicList.get(position);
if (music!=null){
setMusic(music);
playOrPause();
}
}
}
//真·随机播放
public void randomPlay(){
position=random.nextInt(upperBound - lowerBound + 1) + lowerBound;
setData(position);
playOrPause();
}
//单曲循环
public void loop(){
setData(position);
playOrPause();
}
public void setStatus(int status){
this.status=status;
}
public int getStatus() {
return status;
}
public Music getNowPlay(){
return music;
}
//播放
public void playOrPause(){
if (mediaPlayer.isPlaying()){
mediaPlayer.pause();
}
else {
mediaPlayer.start();
}
}
//进度改变
public void seekTo(int i){
mediaPlayer.seekTo(i);
}
//获取当前的播放进度
public int getNow(){
if (mediaPlayer.isPlaying()){
return mediaPlayer.getCurrentPosition();
}
return 0;
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCompletion(MediaPlayer mp) {
if (status==0){
next();
}
else if (status==1){
randomPlay();
}
else if (status==2){
loop();
}
}
public class MusicBinder extends Binder{
//返回Service对象
MusicService getService(){
return MusicService.this;
}
}
public interface OnStatusChangeListener{
void onChange(Music music);
}
}
源码
下载地址:源码下载