像音樂這種耗時的和適合後臺操作的應當放在Service中進行操作,而不是放在Activity,下面就介紹使用Service的音樂播放器
先創建一個MusicService,在Android Studio中,點擊包名右鍵New–>Service–>Service

如果是按照上面的方法創建的Service,配置清單中會自動生成 改Service的聲明

在MusicService中的Java代碼,裏面包含了音樂的相關操作複寫了onCreate()用於初始化播放器
public class MusicService extends Service {
private String path = "mnt/sdcard/123.mp3";
private MediaPlayer player;
@Override
public IBinder onBind(Intent intent) {
//當執行完了onCreate後,就會執行onBind把操作歌曲的方法返回
return new MyBinder();
}
@Override
public void onCreate() {
super.onCreate();
//這裏只執行一次,用於準備播放器
player = new MediaPlayer();
try {
player.setDataSource(path);
//準備資源
player.prepare();
} catch (IOException e) {
e.printStackTrace();
}
Log.e("服務", "準備播放音樂");
}
//該方法包含關於歌曲的操作
public class MyBinder extends Binder {
//判斷是否處於播放狀態
public boolean isPlaying(){
return player.isPlaying();
}
//播放或暫停歌曲
public void play() {
if (player.isPlaying()) {
player.pause();
} else {
player.start();
}
Log.e("服務", "播放音樂");
}
//返回歌曲的長度,單位爲毫秒
public int getDuration(){
return player.getDuration();
}
//返回歌曲目前的進度,單位爲毫秒
public int getCurrenPostion(){
return player.getCurrentPosition();
}
//設置歌曲播放的進度,單位爲毫秒
public void seekTo(int mesc){
player.seekTo(mesc);
}
}
}
佈局中只添加一個按鈕和進度條
<Button
android:id="@+id/play"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="play"
android:text="播放" />
<SeekBar
android:id="@+id/sb"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
在MainActivity中的Java代碼
public class MainActivity extends AppCompatActivity {
private MyConnection conn;
private MusicService.MyBinder musicControl;
private Button playBtn;
private SeekBar seekBar;
private static final int UPDATE_PROGRESS = 0;
//使用handler定時更新進度條
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_PROGRESS:
updateProgress();
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playBtn = (Button) findViewById(R.id.play);
seekBar = (SeekBar) findViewById(R.id.sb);
Intent intent3 = new Intent(this, MusicService.class);
conn = new MyConnection();
//使用混合的方法開啓服務,
startService(intent3);
bindService(intent3, conn, BIND_AUTO_CREATE);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//進度條改變
if (fromUser){
musicControl.seekTo(progress);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
//開始觸摸進度條
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//停止觸摸進度條
}
});
}
private class MyConnection implements ServiceConnection {
//服務啓動完成後會進入到這個方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//獲得service中的MyBinder
musicControl = (MusicService.MyBinder) service;
//更新按鈕的文字
updatePlayText();
//設置進度條的最大值
seekBar.setMax(musicControl.getDuration());
//設置進度條的進度
seekBar.setProgress(musicControl.getCurrenPostion());
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
@Override
protected void onResume() {
super.onResume();
//進入到界面後開始更新進度條
if (musicControl != null){
handler.sendEmptyMessage(UPDATE_PROGRESS);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//退出應用後與service解除綁定
unbindService(conn);
}
@Override
protected void onStop() {
super.onStop();
//停止更新進度條的進度
handler.removeCallbacksAndMessages(null);
}
//更新進度條
private void updateProgress() {
int currenPostion = musicControl.getCurrenPostion();
seekBar.setProgress(currenPostion);
//使用Handler每500毫秒更新一次進度條
handler.sendEmptyMessageDelayed(UPDATE_PROGRESS, 500);
}
//更新按鈕的文字
public void updatePlayText() {
if (musicControl.isPlaying()) {
playBtn.setText("暫停");
handler.sendEmptyMessage(UPDATE_PROGRESS);
} else {
playBtn.setText("播放");
}
}
//調用MyBinder中的play()方法
public void play(View view) {
musicControl.play();
updatePlayText();
}
}
最後別忘了添加讀寫內存卡的權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
效果圖

既然說到音樂播放器了,就順便說說如何播放網絡上的音樂,這是個很重要的功能,其實跟播放本地的差不多,只是用了異步準備,使用setOnPreparedListener()監聽是否準備完成纔去播放
private MediaPlayer player;
if (player == null){
//如果爲空就new我一個
player = new MediaPlayer();
try {
player.setDataSource("http://www.w3school.com.cn/i/horse.mp3");
//異步準備
player.prepareAsync();
//添加準備好的監聽
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//如果準備好了,就會進行這個方法
mp.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}else {
//判斷是否處於播放狀態
if (player.isPlaying()){
player.pause();
}else {
player.start();
}
}
要訪問網絡,就別忘了加權限
<uses-permission android:name="android.permission.INTERNET"/>