自定义音乐播放器
本节通过服务与 SeekBar 的使用完成自定义音乐播放器项目
通过在 MusicService.java 文件中指定要播放音乐的路径,来选择播放网络上或者本地存储中的音乐。
注意:如果播放的是网络上的音乐,不要忘记在清单文件中添加访问网络的权限哦~
布局文件
activity_main.xml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical">
<Button
android:id="@+id/play_button"
style="@style/MyButtonStyle"
android:text="@string/play"
android:onClick="play"/>
<Button
android:id="@+id/pause_button"
style="@style/MyButtonStyle"
android:text="@string/pause"
android:onClick="pause"/>
<Button
android:id="@+id/continue_button"
style="@style/MyButtonStyle"
android:text="@string/continue_button"
android:onClick="continuePlay"/>
<TextView
android:id="@+id/time_textview"
style="@style/MyButtonStyle"
android:text="time"/>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
主界面
MainActivity.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
static SeekBar seekBar;
static TextView timeTextView;
static Calendar calendar;
static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss");
MusicInterface musicInterface;
Intent intent;
MyServiceConnection conn;
static Handler handler = new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
Bundle bundle = msg.getData();
int max = bundle.getInt("max");
int position = bundle.getInt("position");
seekBar.setMax(max);
seekBar.setProgress(position);
//将毫秒转为相应的时间
calendar = Calendar.getInstance();
calendar.setTimeInMillis(max);
Date date = calendar.getTime();
String total = simpleDateFormat.format(date);
calendar.setTimeInMillis(position);
date = calendar.getTime();
simpleDateFormat = new SimpleDateFormat("mm:ss");
String current = simpleDateFormat.format(date);
timeTextView.setText(current + "/" + total);
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
intent = new Intent(this, MusicService.class);
startService(intent);
conn = new MyServiceConnection();
bindService(intent, conn, BIND_AUTO_CREATE);
}
public void initView(){
seekBar = (SeekBar) findViewById(R.id.seekbar);
seekBar.setOnSeekBarChangeListener(new MyOnSeekBarChangeListener());
timeTextView= (TextView) findViewById(R.id.time_textview);
}
class MyOnSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener{
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
/**
* 当滑动seekBar松开手后触发的事件
* @param seekBar
*/
public void onStopTrackingTouch(SeekBar seekBar) {
int position = seekBar.getProgress();
musicInterface.seekTo(position);
}
}
class MyServiceConnection implements ServiceConnection{
public void onServiceConnected(ComponentName name, IBinder service) {
musicInterface = (MusicInterface) service;
}
public void onServiceDisconnected(ComponentName name) {
}
}
/**
* 开始播放音乐
* @param v
*/
public void play(View v){
musicInterface.play();
}
/**
* 暂停播放
* @param v
*/
public void pause(View v){
musicInterface.pause();
}
/**
* 继续播放
* @param v
*/
public void continuePlay(View v){
musicInterface.continuePlay();
}
/**
* 进程销毁后,解绑服务,停止服务
*/
protected void onDestroy() {
super.onDestroy();
if(conn != null) {
unbindService(conn);
stopService(intent);
}
}
}
自定义中间人接口
MusicInterface.java1
2
3
4
5
6public interface MusicInterface {
void play();
void pause();
void continuePlay();
void seekTo(int position);
}
自定义服务
MusicService.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class MusicService extends Service {
MediaPlayer player;
Timer timer;
public void onCreate() {
super.onCreate();
player = new MediaPlayer();
}
public void onDestroy() {
super.onDestroy();
if(player != null) {
player.stop();
player.release();
player = null;
}
if(timer != null){
timer.cancel();
timer = null;
}
}
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return new MusicController();
}
class MusicController extends Binder implements MusicInterface{
public void play() {
MusicService.this.play();
}
public void pause() {
MusicService.this.pause();
}
public void continuePlay() {
MusicService.this.continuePlay();
}
public void seekTo(int position) {
MusicService.this.seekTo(position);
}
}
public void play(){
if(player != null) {
player.reset();
try {
//播放本地音乐
String path = getFilesDir() + "/gaobie.mp3";
//播放网络音乐
//String path = "http://www.hello.com/a.mp3";
player.setDataSource(path);
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.start();
addTimer();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void pause(){
player.pause();
}
public void continuePlay(){
player.start();
}
/**
* 播放指定位置的音乐
* @param position
*/
public void seekTo(int position){
player.seekTo(position);
}
/**
* 添加计时器,周期性的执行run方法
*/
public void addTimer(){
if(timer == null){
timer = new Timer();
}
timer.schedule(new TimerTask() {
public void run() {
Message msg = Message.obtain();
Bundle bundle = new Bundle();
bundle.putInt("max", player.getDuration());
bundle.putInt("position", player.getCurrentPosition());
msg.setData(bundle);
MainActivity.handler.sendMessage(msg);
}
}, 5, 500);
}
}