Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android-簡單音樂播放器的總結

android-簡單音樂播放器的總結

編輯:關於Android編程

[java] 

業務:android的程序,實現播放音樂的功能。

知識點:

1.使用了android的四大組件中的三個(Activity,Service,Broadcast)

activity與serivice之間的通信用廣播Broadcast組件實現,程序中有10多個廣播的發布和接收。

2.還使用了線程和Application類來保存全局性的數據。

在Service中啟動一個線程是為了在activity需要的時候,不間斷地給activity發布更新進度的廣播,activity收到後再界面上展示出來。

難點:

個人感覺廣播雖然多,但是邏輯上一般,不是很復雜,稍微比較難理解的是線程的啟動和停止條件的判段和service中Destroy方法中的收尾清理工作。

1.在這幾種條件下需要喚醒線程。

1)play()方法中,當開始播放音樂的時候,讓它就開始干活。

2)seekto()方法中,當拖動seekBar需要重新定位並且播放音樂的時候,讓它就開始干活。

3)當activity發布廣播,請求service發布一個更新進度的廣播的時候需要喚醒線程,讓它就開始干活。

4)Service方法要退出銷毀的時候需要喚醒線程,讓其退出循環。

完整項目代碼:

 

 


部分代碼:

主Activity的全部代碼


[java] package com.tarena.day1901; 
 
 
import com.tarena.entity.Music; 
import com.tarena.utils.Consts; 
import com.tarena.utils.FormatUtils; 
 
import android.app.Activity; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ListView; 
import android.widget.SeekBar; 
import android.widget.SeekBar.OnSeekBarChangeListener; 
import android.widget.TextView; 
 
public class MainActivity extends Activity { 
     
    private ListView lvMusics; 
    private MenuInflater inflater; 
    private MusicAdapter adapter; 
    private Button btnPlayOrPause; 
    private MusicApplication app; 
    private TextView tvMusicName; 
    private TextView tvDuration; 
    private InnerBroadcastReceiver receiver; 
    private SeekBar sbProgress; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        inflater=getMenuInflater();  
        app=(MusicApplication)getApplication(); 
        //設置界面  
        setupView(); 
        addlistener(); 
        //啟動service  
        Intent intent=new Intent(this, MusicService.class); 
        startService(intent); 
        //創建一個廣播接收器  
        createReceiver(); 
    } 
     
 
    //activity啟動,發送廣播給service告知需要發送進度更新的廣播  
    @Override 
    protected void onStart() { 
        super.onStart(); 
         
        Intent intent=new Intent(Consts.ACTION_NEED_UPDATE_PROGRESS); 
        intent.putExtra(Consts.EXTRA_NEED_UPDATE_PROGRESS, true); 
        sendBroadcast(intent); 
        Log.i("info", "onStart"); 
    } 
    @Override 
    protected void onResume() { 
        Log.i("info", "onREsume"); 
        super.onResume(); 
    } 
  //activity停止,發送廣播給service告知可以停止發送進度更新的廣播  
    @Override 
    protected void onStop() { 
        super.onStop(); 
        Intent intent=new Intent(Consts.ACTION_NEED_UPDATE_PROGRESS); 
        intent.putExtra(Consts.EXTRA_NEED_UPDATE_PROGRESS, false); 
        sendBroadcast(intent); 
    } 
    @Override 
    protected void onDestroy() { 
        super.onDestroy(); 
        unregisterReceiver(receiver);//MainActivity銷毀的時候,對廣播接收器,解除注冊  
    } 
     
  
    //設置界面  
    public void setupView(){ 
        lvMusics=(ListView)findViewById(R.id.lvMusics); 
        adapter=new MusicAdapter(this); 
        lvMusics.setAdapter(adapter); 
         
        btnPlayOrPause=(Button)findViewById(R.id.btnPlayOrPause); 
        tvMusicName=(TextView)findViewById(R.id.tvMusicName); 
        tvDuration=(TextView)findViewById(R.id.tvDuration); 
        sbProgress=(SeekBar)findViewById(R.id.sbProgress); 
    } 
    //添加菜單  
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
        inflater.inflate(R.menu.opts,menu); 
        return super.onCreateOptionsMenu(menu); 
    } 
    //選擇系統菜單選項,發送廣播  
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
        Intent intent=null; 
        switch (item.getItemId()) { 
        case R.id.menu_sub_loop: 
            intent=new Intent(Consts.ACTION_PLAY_MODE); 
            intent.putExtra(Consts.EXTRA_PLAY_MODE, Consts.PLAY_MODE_LOOP); 
            sendBroadcast(intent); 
            Log.i("info", "循環"); 
            break; 
        case R.id.menu_sub_random: 
            intent=new Intent(Consts.ACTION_PLAY_MODE); 
            intent.putExtra(Consts.EXTRA_PLAY_MODE, Consts.PLAY_MODE_RADOM); 
            sendBroadcast(intent); 
            Log.i("info", "隨機"); 
            break; 
        case R.id.menu_opts_exit: 
            intent=new Intent(Consts.ACTION_APP_STOPED); 
            sendBroadcast(intent); 
            finish(); 
            break; 
        } 
 
        return super.onOptionsItemSelected(item); 
    } 
    //監聽用戶拖動seekbar,並記錄拖動的位置  
    private void addlistener() { 
        sbProgress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 
             
            @Override 
            public void onStopTrackingTouch(SeekBar seekBar) { 
                // TODO Auto-generated method stub  
                 
            } 
             
            @Override 
            public void onStartTrackingTouch(SeekBar seekBar) { 
                // TODO Auto-generated method stub  
                 
            } 
             
            @Override 
            public void onProgressChanged(SeekBar seekBar, int progress, 
                    boolean fromUser) { 
                if(fromUser){ 
                    Intent intent=new Intent(Consts.ACTION_SEEK_TO); 
                    intent.putExtra(Consts.EXTRA_SEEK_TO, progress); 
                    sendBroadcast(intent); 
                } 
                 
            } 
        }); 
         
    } 
   //用戶不同的操作,執行相應的操作  
    public void doClick(View v){ 
        Intent intent=null; 
        switch (v.getId()) { 
        case R.id.btnNext: 
            intent=new Intent(Consts.ACTION_PLAY_NEXT); 
            btnPlayOrPause.setText("暫停"); 
            break; 
        case R.id.btnPlayOrPause: 
            String text=((Button)v).getText().toString(); 
            if("播放".equals(text)){ 
                intent=new Intent(Consts.ACTION_PLAY); 
                ((Button)v).setText("暫停"); 
            }else if("暫停".equals(text)){ 
                intent=new Intent(Consts.ACTION_PAUSE); 
                ((Button)v).setText("播放"); 
            } 
            break; 
        case R.id.btnPrevious: 
            intent=new Intent(Consts.ACTION_PLAY_PREVIOUS); 
            btnPlayOrPause.setText("暫停"); 
            break; 
        } 
        sendBroadcast(intent); 
    } 
    //創建一個廣播接收器  
    private void createReceiver() { 
         receiver=new InnerBroadcastReceiver(); 
         IntentFilter filter=new IntentFilter(); 
         filter.addAction(Consts.ACTION_CURRENT_MUSIC_CHANGE); 
         filter.addAction(Consts.ACTION_START_UPDATE_PROGRESS); 
         filter.addAction(Consts.ACTION_SEND_PLAYING_STATE); 
         registerReceiver(receiver, filter); 
         
    } 
     
    private class InnerBroadcastReceiver extends BroadcastReceiver{ 
 
        @Override 
        public void onReceive(Context context, Intent intent) { 
            String action=intent.getAction(); 
            //接收廣播,音樂變更,前端展示更新為新的音樂的名字和時長  
            if(Consts.ACTION_CURRENT_MUSIC_CHANGE.equals(action)){ 
                Music music=app.getCurrentMusic(); 
                tvMusicName.setText(music.getName()); 
                tvDuration.setText(FormatUtils.format(music.getDuration())); 
            }else if(Consts.ACTION_START_UPDATE_PROGRESS.equals(action)){ 
                //當前播放時長  
                int progress=intent.getIntExtra(Consts.EXTRA_CURRENT_MUSIC_TIME_POSITION, 0); 
                //總時長  
                int Duration = (int)app.getCurrentMusic().getDuration(); 
                tvDuration.setText(FormatUtils.format(progress));//在界面顯示歌曲已播放時長  
                sbProgress.setProgress(progress*100/Duration); 
            }else if(Consts.ACTION_SEND_PLAYING_STATE.equals(action)){ 
                int state=intent.getIntExtra(Consts.EXTRA_PLAY_STATE, Consts.STATE_OTHERS); 
                Music m=app.getCurrentMusic(); 
                int progress=intent.getIntExtra(Consts.EXTRA_CURRENT_MUSIC_TIME_POSITION, 0); 
                int Duration = (int)app.getCurrentMusic().getDuration(); 
                tvDuration.setText(FormatUtils.format(progress));//在界面顯示歌曲已播放時長  
                sbProgress.setProgress(progress*100/Duration); 
                tvMusicName.setText(m.getName()); 
                if(state==Consts.STATE_PAUSE){ 
                    btnPlayOrPause.setText("播放"); 
                }else if(state==Consts.STATE_ISPLAYING){ 
                    btnPlayOrPause.setText("暫停"); 
                } 
            } 
             
        } 
    }    
   

package com.tarena.day1901;


import com.tarena.entity.Music;
import com.tarena.utils.Consts;
import com.tarena.utils.FormatUtils;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class MainActivity extends Activity {
 
 private ListView lvMusics;
 private MenuInflater inflater;
 private MusicAdapter adapter;
 private Button btnPlayOrPause;
 private MusicApplication app;
 private TextView tvMusicName;
 private TextView tvDuration;
 private InnerBroadcastReceiver receiver;
 private SeekBar sbProgress;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        inflater=getMenuInflater();
        app=(MusicApplication)getApplication();
        //設置界面
        setupView();
        addlistener();
        //啟動service
        Intent intent=new Intent(this, MusicService.class);
        startService(intent);
        //創建一個廣播接收器
        createReceiver();
    }
   

 //activity啟動,發送廣播給service告知需要發送進度更新的廣播
    @Override
    protected void onStart() {
     super.onStart();
     
     Intent intent=new Intent(Consts.ACTION_NEED_UPDATE_PROGRESS);
     intent.putExtra(Consts.EXTRA_NEED_UPDATE_PROGRESS, true);
     sendBroadcast(intent);
     Log.i("info", "onStart");
    }
    @Override
    protected void onResume() {
     Log.i("info", "onREsume");
     super.onResume();
    }
  //activity停止,發送廣播給service告知可以停止發送進度更新的廣播
    @Override
    protected void onStop() {
     super.onStop();
     Intent intent=new Intent(Consts.ACTION_NEED_UPDATE_PROGRESS);
     intent.putExtra(Consts.EXTRA_NEED_UPDATE_PROGRESS, false);
     sendBroadcast(intent);
    }
    @Override
    protected void onDestroy() {
     super.onDestroy();
     unregisterReceiver(receiver);//MainActivity銷毀的時候,對廣播接收器,解除注冊
    }
   
 
 //設置界面
    public void setupView(){
     lvMusics=(ListView)findViewById(R.id.lvMusics);
     adapter=new MusicAdapter(this);
     lvMusics.setAdapter(adapter);
     
     btnPlayOrPause=(Button)findViewById(R.id.btnPlayOrPause);
     tvMusicName=(TextView)findViewById(R.id.tvMusicName);
     tvDuration=(TextView)findViewById(R.id.tvDuration);
     sbProgress=(SeekBar)findViewById(R.id.sbProgress);
    }
    //添加菜單
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
     inflater.inflate(R.menu.opts,menu);
     return super.onCreateOptionsMenu(menu);
    }
    //選擇系統菜單選項,發送廣播
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
     Intent intent=null;
     switch (item.getItemId()) {
  case R.id.menu_sub_loop:
   intent=new Intent(Consts.ACTION_PLAY_MODE);
   intent.putExtra(Consts.EXTRA_PLAY_MODE, Consts.PLAY_MODE_LOOP);
      sendBroadcast(intent);
      Log.i("info", "循環");
   break;
  case R.id.menu_sub_random:
   intent=new Intent(Consts.ACTION_PLAY_MODE);
   intent.putExtra(Consts.EXTRA_PLAY_MODE, Consts.PLAY_MODE_RADOM);
      sendBroadcast(intent);
      Log.i("info", "隨機");
   break;
  case R.id.menu_opts_exit:
   intent=new Intent(Consts.ACTION_APP_STOPED);
      sendBroadcast(intent);
   finish();
   break;
  }

     return super.onOptionsItemSelected(item);
    }
    //監聽用戶拖動seekbar,並記錄拖動的位置
    private void addlistener() {
    sbProgress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
   
   @Override
   public void onStopTrackingTouch(SeekBar seekBar) {
    // TODO Auto-generated method stub
    
   }
   
   @Override
   public void onStartTrackingTouch(SeekBar seekBar) {
    // TODO Auto-generated method stub
    
   }
   
   @Override
   public void onProgressChanged(SeekBar seekBar, int progress,
     boolean fromUser) {
    if(fromUser){
     Intent intent=new Intent(Consts.ACTION_SEEK_TO);
     intent.putExtra(Consts.EXTRA_SEEK_TO, progress);
     sendBroadcast(intent);
    }
    
   }
  });
    
   }
   //用戶不同的操作,執行相應的操作
    public void doClick(View v){
     Intent intent=null;
     switch (v.getId()) {
  case R.id.btnNext:
   intent=new Intent(Consts.ACTION_PLAY_NEXT);
   btnPlayOrPause.setText("暫停");
   break;
  case R.id.btnPlayOrPause:
   String text=((Button)v).getText().toString();
   if("播放".equals(text)){
    intent=new Intent(Consts.ACTION_PLAY);
    ((Button)v).setText("暫停");
   }else if("暫停".equals(text)){
    intent=new Intent(Consts.ACTION_PAUSE);
    ((Button)v).setText("播放");
   }
   break;
  case R.id.btnPrevious:
   intent=new Intent(Consts.ACTION_PLAY_PREVIOUS);
   btnPlayOrPause.setText("暫停");
   break;
  }
     sendBroadcast(intent);
    }
    //創建一個廣播接收器
    private void createReceiver() {
      receiver=new InnerBroadcastReceiver();
      IntentFilter filter=new IntentFilter();
      filter.addAction(Consts.ACTION_CURRENT_MUSIC_CHANGE);
      filter.addAction(Consts.ACTION_START_UPDATE_PROGRESS);
      filter.addAction(Consts.ACTION_SEND_PLAYING_STATE);
      registerReceiver(receiver, filter);
  
 }
   
    private class InnerBroadcastReceiver extends BroadcastReceiver{

  @Override
  public void onReceive(Context context, Intent intent) {
   String action=intent.getAction();
   //接收廣播,音樂變更,前端展示更新為新的音樂的名字和時長
   if(Consts.ACTION_CURRENT_MUSIC_CHANGE.equals(action)){
    Music music=app.getCurrentMusic();
    tvMusicName.setText(music.getName());
    tvDuration.setText(FormatUtils.format(music.getDuration()));
   }else if(Consts.ACTION_START_UPDATE_PROGRESS.equals(action)){
    //當前播放時長
    int progress=intent.getIntExtra(Consts.EXTRA_CURRENT_MUSIC_TIME_POSITION, 0);
    //總時長
    int Duration = (int)app.getCurrentMusic().getDuration();
    tvDuration.setText(FormatUtils.format(progress));//在界面顯示歌曲已播放時長
    sbProgress.setProgress(progress*100/Duration);
   }else if(Consts.ACTION_SEND_PLAYING_STATE.equals(action)){
    int state=intent.getIntExtra(Consts.EXTRA_PLAY_STATE, Consts.STATE_OTHERS);
    Music m=app.getCurrentMusic();
    int progress=intent.getIntExtra(Consts.EXTRA_CURRENT_MUSIC_TIME_POSITION, 0);
    int Duration = (int)app.getCurrentMusic().getDuration();
    tvDuration.setText(FormatUtils.format(progress));//在界面顯示歌曲已播放時長
    sbProgress.setProgress(progress*100/Duration);
    tvMusicName.setText(m.getName());
    if(state==Consts.STATE_PAUSE){
     btnPlayOrPause.setText("播放");
    }else if(state==Consts.STATE_ISPLAYING){
     btnPlayOrPause.setText("暫停");
    }
   }
   
  }
    } 
 
}

 

MusicService的完整代碼

 


[java] view plaincopyprint?package com.tarena.day1901; 
 
import java.io.IOException; 
import java.util.Random; 
 
import com.tarena.entity.Music; 
import com.tarena.utils.Consts; 
 
import android.app.Service; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnCompletionListener; 
import android.os.IBinder; 
import android.util.Log; 
 
public class MusicService extends Service { 
    private MediaPlayer player; 
    private MusicApplication app; 
    private boolean isPause; 
    private boolean needUpdate; //需要發布更新進度  
    private boolean isLoop;//控制循環語句  
    private int playMode; 
    private Random random; 
    private InnerBroadcastReceiver receiver; 
    private Thread workThread; 
 
    @Override 
    public void onCreate() { 
        super.onCreate(); 
        app=(MusicApplication)getApplication(); 
        player=new MediaPlayer(); 
        playMode=Consts.PLAY_MODE_LOOP; 
        isLoop=true; 
        needUpdate=true; 
        random=new Random(); 
        //設置自動播放下一首的監聽器  
        addlistener();       
        //添加接收器       
        createReceiver(); 
        workThread=new Thread(){ 
            public void run() { 
                while(isLoop){ 
                    while(isLoop&&needUpdate&&player.isPlaying()){ 
                        Intent intent=new Intent(Consts.ACTION_START_UPDATE_PROGRESS); 
                        //將當前播放的音樂播放的時間抽的位置包裝傳遞  
                        intent.putExtra(Consts.EXTRA_CURRENT_MUSIC_TIME_POSITION, player.getCurrentPosition()); 
                        sendBroadcast(intent); 
                        try { 
                            sleep(1000); 
                        } catch (InterruptedException e) { 
                            e.printStackTrace(); 
                        } 
                    } 
                    //此工作線程需要不停地循環工作,除非修改循環標志。不需要發送廣播的時候就等待,睡大覺  
                    synchronized (this) { 
                        try { 
                            this.wait(); 
                        } catch (InterruptedException e) { 
                            e.printStackTrace(); 
                        } 
                    } 
                     
                } 
            }; 
        }; 
        workThread.start(); 
    } 
     
    //service銷毀的時候,解除注冊廣播接收器  
    @Override 
    public void onDestroy() { 
        unregisterReceiver(receiver); 
        //喚醒線程,讓線程退出循環  
        isLoop = false; 
        synchronized (workThread) { 
            workThread.notify(); 
        } 
        //如果音樂還在播放,停止其播放  
        if (player.isPlaying()) 
            player.stop(); 
        //釋放資源  
        player.release(); 
        super.onDestroy(); 
    } 
    //如果是isPause狀態值為true,直接播放,else重置player,最後要記得喚醒線程  
    public void play(){ 
        if(isPause){ 
            player.start(); 
        }else{ 
            Music music=app.getCurrentMusic(); 
            String path=music.getMusicPath(); 
            if(path!=null){ 
                try { 
                    player.reset(); 
                    player.setDataSource(path); 
                    player.prepare(); 
                    player.start(); 
                    //當前索引所表示的歌曲變化,發布廣播  
                    Intent intent=new Intent(Consts.ACTION_CURRENT_MUSIC_CHANGE); 
                    sendBroadcast(intent); 
                } catch (IllegalArgumentException e) { 
                    e.printStackTrace(); 
                } catch (IllegalStateException e) { 
                    e.printStackTrace(); 
                } catch (IOException e) { 
                    e.printStackTrace(); 
                } 
            } 
             
             
        } 
        isPause=false;//音樂開始播放,將暫停狀態標志置為false  
        synchronized (workThread) { 
            workThread.notify(); 
        } 
    } 
    //如果正在播放,暫停播放  
    public void pause(){ 
        if(player.isPlaying()){ 
            player.pause(); 
            isPause=true; 
        } 
    } 
    //開始播放後一首  
    public void next(){ 
        int index=app.getCurrentPosition(); 
        switch (playMode) { 
        case Consts.PLAY_MODE_LOOP: 
            if(++index>=app.getPlayListSize()){ 
                index=0; 
            } 
            break; 
        case Consts.PLAY_MODE_RADOM: 
            do { 
                index=random.nextInt(app.getPlayListSize()); 
            } while (index==app.getCurrentPosition()); 
            break; 
        } 
        app.setCurrentPosition(index); 
        isPause=false; 
        play(); 
    } 
    //開始播放前一首  
    public void previous(){ 
        int index=app.getCurrentPosition(); 
        switch (playMode) { 
        case Consts.PLAY_MODE_LOOP: 
            if(--index<=0){ 
                index=app.getPlayListSize()-1; 
            } 
            break; 
        case Consts.PLAY_MODE_RADOM: 
            do { 
                index=random.nextInt(app.getPlayListSize()); 
            } while (index==app.getCurrentPosition()); 
            break; 
        } 
        app.setCurrentPosition(index); 
        isPause=false; 
        play(); 
    } 
    //定位到指定的時間值開始播放  
    public void seekTo(int positon){ 
        player.seekTo(positon); 
        player.start(); 
        synchronized (workThread) { 
            workThread.notify(); 
        } 
    } 
     
    @Override 
    public IBinder onBind(Intent intent) { 
        return null; 
    } 
     
    //設置自動播放下一首  
    public void addlistener(){ 
        player.setOnCompletionListener(new OnCompletionListener() { 
             
            @Override 
            public void onCompletion(MediaPlayer mp) { 
                next(); 
            } 
        }); 
    } 
    //添加接收器  
    private void createReceiver() { 
        receiver=new InnerBroadcastReceiver(); 
        IntentFilter filter=new IntentFilter(); 
        filter.addAction(Consts.ACTION_PAUSE); 
        filter.addAction(Consts.ACTION_PLAY); 
        filter.addAction(Consts.ACTION_PLAY_NEXT); 
        filter.addAction(Consts.ACTION_PLAY_PREVIOUS); 
        filter.addAction(Consts.ACTION_PLAY_MODE); 
        filter.addAction(Consts.ACTION_APP_STOPED); 
        filter.addAction(Consts.ACTION_NEED_UPDATE_PROGRESS); 
        filter.addAction(Consts.ACTION_SEEK_TO); 
        registerReceiver(receiver, filter); 
    } 
    //接收器類  
    private class InnerBroadcastReceiver extends BroadcastReceiver{ 
 
        @Override 
        public void onReceive(Context context, Intent intent) { 
            String action=intent.getAction(); 
            if(Consts.ACTION_PLAY.equals(action)){ 
                play(); 
            }else if(Consts.ACTION_PAUSE.equals(action)){ 
                pause(); 
            }else if(Consts.ACTION_PLAY_NEXT.equals(action)){ 
                next(); 
            }else if(Consts.ACTION_PLAY_PREVIOUS.equals(action)){ 
                previous(); 
            }else if(Consts.ACTION_PLAY_MODE.equals(action)){ 
                playMode=intent.getIntExtra(Consts.EXTRA_PLAY_MODE, Consts.PLAY_MODE_LOOP); 
                 
            } 
            //獲取並判斷當前是否需要發送更新進度的廣播  
            else if(Consts.ACTION_NEED_UPDATE_PROGRESS.equals(action)){ 
                needUpdate=intent.getBooleanExtra(Consts.EXTRA_NEED_UPDATE_PROGRESS, true); 
                if(needUpdate){ 
                    synchronized (workThread) { 
                        workThread.notify(); 
                    } 
                    //更新進度的時候,同時發送音樂播放器的狀態(是否正在播放、播放的音樂的位置)  
                    Intent intent2=new Intent(Consts.ACTION_SEND_PLAYING_STATE); 
                    int state=Consts.STATE_OTHERS; 
                    int position=0; 
                    if(player.isPlaying()){ 
                        state=Consts.STATE_ISPLAYING; 
                         
                    }else if(isPause){ 
                        state=Consts.STATE_PAUSE; 
                    } 
                    position=player.getCurrentPosition(); 
                    intent2.putExtra(Consts.EXTRA_CURRENT_MUSIC_TIME_POSITION, position); 
                    intent2.putExtra(Consts.EXTRA_PLAY_STATE, state); 
                    sendBroadcast(intent2); 
                } 
            //根據拖動的位置,計算應當開始播放的時間值    
            }else if(Consts.ACTION_SEEK_TO.equals(action)){ 
                int progress=intent.getIntExtra(Consts.EXTRA_SEEK_TO, player.getCurrentPosition()); 
                int duration=(int)app.getCurrentMusic().getDuration(); 
                seekTo(progress*duration/100); 
            }else if(Consts.ACTION_APP_STOPED.equals(action)){ 
                stopSelf(); 
            }    
             
        } 
         
    } 

package com.tarena.day1901;

import java.io.IOException;
import java.util.Random;

import com.tarena.entity.Music;
import com.tarena.utils.Consts;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;
import android.util.Log;

public class MusicService extends Service {
 private MediaPlayer player;
 private MusicApplication app;
 private boolean isPause;
 private boolean needUpdate; //需要發布更新進度
 private boolean isLoop;//控制循環語句
 private int playMode;
 private Random random;
 private InnerBroadcastReceiver receiver;
 private Thread workThread;

 @Override
 public void onCreate() {
  super.onCreate();
  app=(MusicApplication)getApplication();
  player=new MediaPlayer();
  playMode=Consts.PLAY_MODE_LOOP;
  isLoop=true;
  needUpdate=true;
  random=new Random();
  //設置自動播放下一首的監聽器
  addlistener();  
  //添加接收器  
  createReceiver();
  workThread=new Thread(){
   public void run() {
    while(isLoop){
     while(isLoop&&needUpdate&&player.isPlaying()){
      Intent intent=new Intent(Consts.ACTION_START_UPDATE_PROGRESS);
      //將當前播放的音樂播放的時間抽的位置包裝傳遞
      intent.putExtra(Consts.EXTRA_CURRENT_MUSIC_TIME_POSITION, player.getCurrentPosition());
      sendBroadcast(intent);
      try {
       sleep(1000);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
     }
     //此工作線程需要不停地循環工作,除非修改循環標志。不需要發送廣播的時候就等待,睡大覺
     synchronized (this) {
      try {
       this.wait();
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
     }
     
    }
   };
  };
  workThread.start();
 }
 
 //service銷毀的時候,解除注冊廣播接收器
 @Override
 public void onDestroy() {
  unregisterReceiver(receiver);
  //喚醒線程,讓線程退出循環
  isLoop = false;
  synchronized (workThread) {
   workThread.notify();
  }
  //如果音樂還在播放,停止其播放
  if (player.isPlaying())
   player.stop();
  //釋放資源
  player.release();
  super.onDestroy();
 }
 //如果是isPause狀態值為true,直接播放,else重置player,最後要記得喚醒線程
 public void play(){
  if(isPause){
   player.start();
  }else{
   Music music=app.getCurrentMusic();
   String path=music.getMusicPath();
   if(path!=null){
    try {
     player.reset();
     player.setDataSource(path);
     player.prepare();
     player.start();
     //當前索引所表示的歌曲變化,發布廣播
     Intent intent=new Intent(Consts.ACTION_CURRENT_MUSIC_CHANGE);
     sendBroadcast(intent);
    } catch (IllegalArgumentException e) {
     e.printStackTrace();
    } catch (IllegalStateException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   
   
  }
  isPause=false;//音樂開始播放,將暫停狀態標志置為false
  synchronized (workThread) {
   workThread.notify();
  }
 }
 //如果正在播放,暫停播放
 public void pause(){
  if(player.isPlaying()){
   player.pause();
   isPause=true;
  }
 }
 //開始播放後一首
 public void next(){
  int index=app.getCurrentPosition();
  switch (playMode) {
  case Consts.PLAY_MODE_LOOP:
   if(++index>=app.getPlayListSize()){
    index=0;
   }
   break;
  case Consts.PLAY_MODE_RADOM:
   do {
    index=random.nextInt(app.getPlayListSize());
   } while (index==app.getCurrentPosition());
   break;
  }
  app.setCurrentPosition(index);
  isPause=false;
  play();
 }
 //開始播放前一首
 public void previous(){
  int index=app.getCurrentPosition();
  switch (playMode) {
  case Consts.PLAY_MODE_LOOP:
   if(--index<=0){
    index=app.getPlayListSize()-1;
   }
   break;
  case Consts.PLAY_MODE_RADOM:
   do {
    index=random.nextInt(app.getPlayListSize());
   } while (index==app.getCurrentPosition());
   break;
  }
  app.setCurrentPosition(index);
  isPause=false;
  play();
 }
 //定位到指定的時間值開始播放
 public void seekTo(int positon){
  player.seekTo(positon);
  player.start();
  synchronized (workThread) {
   workThread.notify();
  }
 }
 
 @Override
 public IBinder onBind(Intent intent) {
  return null;
 }
 
 //設置自動播放下一首
 public void addlistener(){
  player.setOnCompletionListener(new OnCompletionListener() {
   
   @Override
   public void onCompletion(MediaPlayer mp) {
    next();
   }
  });
 }
 //添加接收器
 private void createReceiver() {
  receiver=new InnerBroadcastReceiver();
  IntentFilter filter=new IntentFilter();
  filter.addAction(Consts.ACTION_PAUSE);
  filter.addAction(Consts.ACTION_PLAY);
  filter.addAction(Consts.ACTION_PLAY_NEXT);
  filter.addAction(Consts.ACTION_PLAY_PREVIOUS);
  filter.addAction(Consts.ACTION_PLAY_MODE);
  filter.addAction(Consts.ACTION_APP_STOPED);
  filter.addAction(Consts.ACTION_NEED_UPDATE_PROGRESS);
  filter.addAction(Consts.ACTION_SEEK_TO);
  registerReceiver(receiver, filter);
 }
 //接收器類
 private class InnerBroadcastReceiver extends BroadcastReceiver{

  @Override
  public void onReceive(Context context, Intent intent) {
   String action=intent.getAction();
   if(Consts.ACTION_PLAY.equals(action)){
    play();
   }else if(Consts.ACTION_PAUSE.equals(action)){
    pause();
   }else if(Consts.ACTION_PLAY_NEXT.equals(action)){
    next();
   }else if(Consts.ACTION_PLAY_PREVIOUS.equals(action)){
    previous();
   }else if(Consts.ACTION_PLAY_MODE.equals(action)){
    playMode=intent.getIntExtra(Consts.EXTRA_PLAY_MODE, Consts.PLAY_MODE_LOOP);
    
   }
   //獲取並判斷當前是否需要發送更新進度的廣播
   else if(Consts.ACTION_NEED_UPDATE_PROGRESS.equals(action)){
    needUpdate=intent.getBooleanExtra(Consts.EXTRA_NEED_UPDATE_PROGRESS, true);
    if(needUpdate){
     synchronized (workThread) {
      workThread.notify();
     }
     //更新進度的時候,同時發送音樂播放器的狀態(是否正在播放、播放的音樂的位置)
     Intent intent2=new Intent(Consts.ACTION_SEND_PLAYING_STATE);
     int state=Consts.STATE_OTHERS;
     int position=0;
     if(player.isPlaying()){
      state=Consts.STATE_ISPLAYING;
      
     }else if(isPause){
      state=Consts.STATE_PAUSE;
     }
     position=player.getCurrentPosition();
     intent2.putExtra(Consts.EXTRA_CURRENT_MUSIC_TIME_POSITION, position);
     intent2.putExtra(Consts.EXTRA_PLAY_STATE, state);
     sendBroadcast(intent2);
    }
   //根據拖動的位置,計算應當開始播放的時間值 
   }else if(Consts.ACTION_SEEK_TO.equals(action)){
    int progress=intent.getIntExtra(Consts.EXTRA_SEEK_TO, player.getCurrentPosition());
    int duration=(int)app.getCurrentMusic().getDuration();
    seekTo(progress*duration/100);
   }else if(Consts.ACTION_APP_STOPED.equals(action)){
    stopSelf();
   } 
   
  }
  
 }
}

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved