通过音频播放器可以实现播放音乐的功能,使用的支持类是MediaPlayer
使用MediaPlayer的流程:
1) 建立对象
2) 设置要播放的音乐(DataSource)
3) 进行播放准备(prepare())
4) 进行播放(start())
5) 在播放状态中,可以通过SeekTo()方法来调整播放位置
6) 如果设置了循环播放(looping为true),则播放完成时,会重新开始播放。
7) 在播放状态中,可以通过pause()方法来暂停音乐的播放,也可以通过start()恢复播放。
8) 如果没有设置循环播放(looping为false),则播放完成后进入PlayBack Complete状态(注意,不是停止状态),这时可以通过start()重新播放音乐。
9) 如果在之前的各个状态中调用stop()就会进入停止状态,这时需要重新准备(prepare()),才可以播放。
10)如果想彻底释放资源,需要调用release()方法,这样才算播放结束。
下面实现播放SD卡中音乐的功能
public class MainActivity extends Activity {
private MediaPlayer player;
private String filePath = "/mnt/sdcard/a.mp3";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 先建立player对象
player = new MediaPlayer();
// 设置数据来源
try {
// 使用这种方法创建, 不需要prepare,可以直接播放
player = MediaPlayer.create(this, R.raw.a);
// 准备
// player.prepare();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "播放出现问题, 请与厂商联系",
Toast.LENGTH_SHORT).show();
}
// 设置
// player.setLooping(false);
// player.setVolume(1.0f, 1.0f);
// 播放
player.start();
}
@Override
protected void onDestroy() {
// 退出时释放播放的音乐
try {
if (player != null) {
if (player.isPlaying()) {
player.stop();
}
player.release();
}
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy();
}
}
可以加入一些控制按钮,来完成播放操作。
还可以在数据库中建立播放的音乐列表数据,通过读取数据库,取得这些音乐,并列表显示到界面中。
public class MainActivity extends Activity {
private MediaPlayer player;
private String filePath = "/mnt/sdcard/a.mp3";
private String name = "Fly me to the moon";
private Button preBtn;
private Button nextBtn;
private Button playBtn;
private TextView songName;
private TextView timeText;
private SeekBar seekbar;
// 总时长的文字
private String allTimeText;
// 加入子线程通道
private Handler handler;
// 取得所有要播放歌曲的集合
private List<Map<String, Object>> allValues;
private DataBaseConnection dbc;
// 当前播放的歌曲索引
private int playedIndex = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 建立数据库连接
dbc = new DataBaseConnection(this);
// 读取数据库中保存的音乐播放列表
allValues = MusicDAOUtils.listData(dbc.getReadableDatabase());
// 初始化所有组件
preBtn = (Button) findViewById(R.id.pre_btn);
playBtn = (Button) findViewById(R.id.play_btn);
nextBtn = (Button) findViewById(R.id.next_btn);
songName = (TextView) findViewById(R.id.song_name);
timeText = (TextView) findViewById(R.id.time_text);
seekbar = (SeekBar) findViewById(R.id.seekbar);
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
seekbar.setProgress(player.getCurrentPosition());
timeText.setText(changeTimeFormat(player.getCurrentPosition())
+ " / " + allTimeText);
}
};
// 初始化第一首歌曲
setPlayedMusic();
// 设置
// player.setLooping(false);
// player.setVolume(1.0f, 1.0f);
// 播放
playBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (player.isPlaying()) {
player.pause();
playBtn.setBackgroundResource(R.drawable.bt_widget_play_nor);
} else {
player.start();
playBtn.setBackgroundResource(R.drawable.bt_widget_pause_nor);
}
}
});
// 拖动, 并改变播放位置
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// 根据当前SeekBar的位置,让播放器从这个位置开始播放
player.seekTo(seekBar.getProgress());
// 重新播放音乐
player.start();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// 暂停播放音乐
if (player.isPlaying()) {
player.pause();
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// 时间跟着进度条一起走, 前提是用户改变的时候.
if (fromUser) {
timeText.setText(changeTimeFormat(progress) + " / "
+ allTimeText);
}
}
});
// 进行歌曲的切换
preBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (playedIndex == 0) {
Toast.makeText(MainActivity.this, "当前已经是第一首歌,无法切换上一首!",
Toast.LENGTH_LONG).show();
} else {
playedIndex--;
setPlayedMusic();
playBtn.performClick();
}
}
});
nextBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (playedIndex == allValues.size() - 1) {
Toast.makeText(MainActivity.this, "当前已经是最后一首歌,无法切换下一首!",
Toast.LENGTH_LONG).show();
} else {
playedIndex++;
setPlayedMusic();
playBtn.performClick();
}
}
});
// 加入一个子线程,控制拖动条的自动移动
Thread t = new Thread() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
// 如果已经播放了,就移动拖动条,否则不用移动
if (player.isPlaying()) {
handler.sendEmptyMessage(0);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
t.start();
}
// 进行音乐的初始化
public void setPlayedMusic() {
Map<String, Object> map = allValues.get(playedIndex);
filePath = map.get("filePath").toString();
name = map.get("songName").toString();
if (player != null) {
if (player.isPlaying()) {
player.stop();
}
player.release();
}
// 先建立player对象
player = new MediaPlayer();
// 设置数据来源
try {
// player = MediaPlayer.create(this, R.raw.a);
player.setDataSource(this, Uri.fromFile(new File(filePath)));
songName.setText(name);
// 准备
player.prepare();
allTimeText = changeTimeFormat(player.getDuration());
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "播放出现问题, 请与厂商联系",
Toast.LENGTH_SHORT).show();
}
// 设置最大值
seekbar.setMax(player.getDuration());
// 计算总播放时间, 并整理成为显示的格式
timeText.setText("00:00 / " + allTimeText);
}
// 算法,根据毫秒, 返回 分钟:秒 的格式
public String changeTimeFormat(int ms) {
System.out.println(ms);
// 转换成秒数
int s = ms / 1000;
System.out.println(s);
// 分钟
int min = s / 60;
System.out.println(min);
// 取得剩余的秒数
s = s % 60;
StringBuilder builder = new StringBuilder();
if (min < 10) {
builder.append("0");
}
builder.append(min);
builder.append(":");
if (s < 10) {
builder.append("0");
}
builder.append(s);
return builder.toString();
}
@Override
protected void onDestroy() {
// 退出时释放播放的音乐
try {
if (player != null) {
if (player.isPlaying()) {
player.stop();
}
player.release();
}
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy();
}
}