1.在sdcard中获取音频文件,实现音乐播放。并且音乐播放要放在服务当中避免受到Activity生命周期影响。
2.使用SeekBar进行拖动时要暂停音乐的播放,避免拖动时进度条的更新。
3.在使用MediaPlayer时要注意重新装载音频文件后要要调用reset()重置。
布局文件很简单这里就不贴出来了。
MainActivity.java
package com.example.musicplayer;
import android.content.Intent;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button bt_sp, bt_next, bt_qt;
private static TextView tv_crt, tv_tol;
private static SeekBar seekBar;
static int count = 0; //count为偶数表示暂停,奇数表示播放
static ArrayList<String> list; //存放所有音乐名
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
bt_sp.setOnClickListener(this);
bt_next.setOnClickListener(this);
bt_qt.setOnClickListener(this);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { //当seekBar被持续拖动时回调
Log.e("changed", progress + "");
int current = (int) (progress * MusicService.mp.getDuration() / 1000.0);
tv_crt.setText(new SimpleDateFormat("mm:ss").format(current)); //更新拖动进度
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) { //当seekBar被拖动时回调
if (bt_sp.getText().toString().equals("暂停")) { //当音乐在播放时拖动
count--;
Intent in = new Intent(MainActivity.this, MusicService.class)
.putExtra("switch", 0xffffffff);
startService(in);
} else { //暂停时拖动
Intent in = new Intent(MainActivity.this, MusicService.class)
.putExtra("switch", 0xffffffff);
startService(in);
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) { //当seekBar拖动停止时回调
count++;
int progress = seekBar.getProgress();
int current = (int) (progress * MusicService.mp.getDuration() / 1000.0);
MusicService.mp.seekTo(current); //在拖动位置处播放
Intent in = new Intent(MainActivity.this, MusicService.class)
.putExtra("switch", 0xffffffff);
startService(in);
}
});
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//判断是否安装sdcard
getAllMusic();
}
}
public void initView() { //获取所有控件实例
bt_sp = (Button) findViewById(R.id.sp);
bt_next = (Button) findViewById(R.id.next);
bt_qt = (Button) findViewById(R.id.quiet);
tv_crt = (TextView) findViewById(R.id.current);
tv_tol = (TextView) findViewById(R.id.total);
seekBar = (SeekBar) findViewById(R.id.seekBar);
}
public void getAllMusic() {
list = new ArrayList<>();
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/music";
Log.e("path", path);
File dir = new File(path); //获取/mnt/media_rw/sdcard/music目录对象
File[] files = dir.listFiles();
getFilesName(files);
}
private void getFilesName(File[] files) {
if (files != null) { // 先判断该目录是否为空
for (File file : files) {
if (file.isDirectory()) {
getFilesName(file.listFiles()); //递归
} else {
String fileName = file.getName();
list.add(fileName);
Log.e("name", fileName);
}
}
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sp: {
count++;
if (count % 2 == 0)
bt_sp.setText("播放");
else
bt_sp.setText("暂停");
Intent in = new Intent(this, MusicService.class)
.putExtra("switch", 0xffffffff);
startService(in);
}
break;
case R.id.next: {
count = 0;
bt_sp.setText("播放");
Intent in = new Intent(this, MusicService.class)
.putExtra("switch", 0xfffffffe);
startService(in);
}
break;
case R.id.quiet:
stopService(new Intent(this, MusicService.class));
finish();
break;
}
}
public static Handler handler = new Handler() { //更新进度条和音乐播放时间
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.obj != null) {
String total = (String) msg.obj;
tv_tol.setText(total);
}
int progress = msg.what;
int current = (int) (progress * MusicService.mp.getDuration() / 1000.0);
seekBar.setProgress(progress);
tv_crt.setText(new SimpleDateFormat("mm:ss").format(current));
}
};
}
MusicService.java
package com.example.musicplayer;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Environment;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
public class MusicService extends Service {
static MediaPlayer mp;
private ArrayList<String> list;
private int flag = 1;
private static final String SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath() + "/music/"; // sdcard路径/mnt/media_rw/sdcard/music
@Override
public void onCreate() {
super.onCreate();
Log.e("service", "服务被启动");
mp = new MediaPlayer();
list = MainActivity.list; //获取所有音乐名
try {
mp.setDataSource(SDCARD + list.get(0)); //设置第一首歌
mp.prepare(); //装载音乐文件资源
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
int num = intent.getIntExtra("switch", 0);
if (num == 0xffffffff) { //按下播放按钮
if (MainActivity.count % 2 == 0) {
mp.pause();
} else {
mp.start();
updateProgress();
}
} else if (num == 0xfffffffe) { //按下下一首按钮
if (flag > 0 && flag <= list.size() - 1) {
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.reset(); //重置
mp.setDataSource(SDCARD + list.get(flag));
mp.prepare(); //装载音乐文件资源
}
} else {
flag = 0;
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.reset(); //重置
mp.setDataSource(SDCARD + list.get(flag));
mp.prepare(); //装载音乐文件资源
}
}
flag++;
}
} catch (IOException e) {
e.printStackTrace();
}
return super.onStartCommand(intent, flags, startId);
}
public void updateProgress() { //更新进度条
new Thread(new Runnable() {
@Override
public void run() {
Message msg = Message.obtain();
msg.obj = getTime();
MainActivity.handler.sendMessage(msg);
while (MainActivity.count % 2 != 0) {
Message msg_ = Message.obtain();
int progress = (int) (mp.getCurrentPosition() * 1000.0 / mp.getDuration());
msg_.what = progress; //获取当前播放位置
MainActivity.handler.sendMessage(msg_);
SystemClock.sleep(1000); //延时一秒钟
}
}
}).start();
Log.e("thread", "更新线程结束");
}
public String getTime() { //将毫秒转换成时间
int total = mp.getDuration();
String format = "mm:ss"; //自定义时间模式
SimpleDateFormat df = new SimpleDateFormat(format);
return df.format(total);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
mp.release(); //释放音乐文件资源
} else
mp.release();
}
Log.e("service", "服务被销毁");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
加上用户权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
效果如下: