在下文中我们实现的简单的音乐播放功能。

​​原创:Android应用开发记录-Andorid歌词秀(2)先来一个音频播放器​​

但是这样的方式在程序退出后播放也会停止,为了解决这个问题,使用的Service类。

在参考网上播放器例子代码的基础上,运用Proxy模式简化的Service的管理和使用。

功能简介:

1.选择手机上的音频,以list形式表示。

2.点击对应标题播放歌曲。

3.点击播放中的歌曲时,暂停播放,再次点击,继续播放。


简单说明

MusicPlaybackService 类

管理MediaPlayer 的生成和创建

实现了Resume功能

播放文件名的设定和取得功能

public class MusicPlaybackService extends Service {
    private MediaPlayer mMediaPlayer = new MediaPlayer();
    private final IBinder mBinder =  new  LocalBinder();
    private int mPausePosition = 0;
    private String mDataSource;
   
    public class LocalBinder extends Binder {  
        public MusicPlaybackService getService() {  
            return MusicPlaybackService.this ;  
        }  
    }  

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
   
    @Override
    public void onCreate() {
        mMediaPlayer = new MediaPlayer();
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        mMediaPlayer.release();
        mMediaPlayer = null;
        super.onDestroy();
    }

    public void setDataSource(String path) { 
        mDataSource = path;
        try{  
            mMediaPlayer.reset();  
            mMediaPlayer.setDataSource(path);  
            mMediaPlayer.prepare();  
        }catch(IOException e) {  
            return;  
        } catch  (IllegalArgumentException e) {  
            return;  
        }  
    }
   
    public String getDataSource(){
        return mDataSource;
    }
   
    public void start() {
        mMediaPlayer.start();  
    }  
   
    public void stop() {  
        mMediaPlayer.stop();  
    }  
   
    public void pause() {
        mPausePosition = getPosition();
        mMediaPlayer.pause();  
    }
   
    public void resume() {  
        seek(mPausePosition);
        mMediaPlayer.start();
    }
   
    public boolean isPlaying() {  
        return mMediaPlayer.isPlaying();  
    }  
   
    public int getDuration() {  
        return mMediaPlayer.getDuration();  
    }  
      
    public int getPosition() {  
        return mMediaPlayer.getCurrentPosition();  
    }  
   
    public long seek(long whereto) {  
        mMediaPlayer.seekTo((int ) whereto);  
        return  whereto;  
    }  
}

 

Service类完成以后,就可以使用的,只是还有点繁琐,能不能包装一下呢?在这个程序中为了简化Service的利用,追加了一个MusicPlaybackServiceProxy类

主要是封装的ServiceConnection关联部分。虽然mPlaybackService 是在绑定后(实际上还要晚一点)才可用的,但是MusicPlaybackServiceProxy随时可用。

代码其实很简单,一看就应该能理解。

public class MusicPlaybackServiceProxy {
    private ContextWrapper mContextWrapper= null;
    private MusicPlaybackService mPlaybackService =  null ;
   
    private ServiceConnection mPlaybackConnection = new ServiceConnection() {  
           public void onServiceConnected(ComponentName className, IBinder service) {    
               mPlaybackService = ((MusicPlaybackService.LocalBinder)service).getService();
           }
 
           public void onServiceDisconnected(ComponentName className) {  
               mPlaybackService = null ; 
           }  
    }; 
   
    MusicPlaybackServiceProxy(ContextWrapper cw){
        mContextWrapper = cw;
    }
   
    void startAndBindService(){
        mContextWrapper.startService(new Intent(mContextWrapper ,MusicPlaybackService.class));          
        mContextWrapper.bindService(new Intent(mContextWrapper, MusicPlaybackService.class), mPlaybackConnection, Context.BIND_AUTO_CREATE);
    }
   
    void stopService(){
        if(mPlaybackService != null){
            mContextWrapper.stopService(new Intent(mContextWrapper ,MusicPlaybackService.class));
        }
    }
   
    public void setDataSource(String path) {  
        mPlaybackService.setDataSource(path);
    }
   
    public String getDataSource(){
        if(mPlaybackService != null){
            return mPlaybackService.getDataSource();
        }else{
            return null;
        }
    }
   
    public void start() {
        if(mPlaybackService != null){
            mPlaybackService.start();
        }
    }  
   
    public void stop(){
        if(mPlaybackService != null){
            mPlaybackService.stop();
        }
    }  
   
    public void pause() {
        if(mPlaybackService != null){
            mPlaybackService.pause();
        }
    }
   
    public void resume() {
        if(mPlaybackService != null){
            mPlaybackService.start();
        }
    }
   
    public boolean isPlaying() {
        if(mPlaybackService != null){
            return mPlaybackService.isPlaying();
        }else{
            return false;
        }
    }  
   
    public int getDuration() {
        if(mPlaybackService != null){
            return mPlaybackService.getDuration();
        }else{
            return 0;
        }
    }  
      
    public int getPosition() {
        if(mPlaybackService != null){
            return mPlaybackService.getPosition();
        }else{
            return 0;
        }
    }  
   
    public long seek(long whereto) {
        if(mPlaybackService != null){
            return mPlaybackService.seek(whereto);
        }else{
            return 0;
        }
    }  

};

 

最后是使用代码的例子,更简单。

public class SubtitleMain extends Activity{
    private Cursor mCursor; 
    private ListView mFilelist;
    private MusicPlaybackServiceProxy mProxy = new MusicPlaybackServiceProxy(this);
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
     
        mProxy.startAndBindService();
       
        mCursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,  null ,
                 null ,null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
        //初始化歌曲列表
        mFilelist = (ListView)findViewById(R.id.audio_file_view);
              
        startManagingCursor(mCursor);
       
        String[] from = new String[] {MediaStore.Audio.Media.TITLE};
        int[] to = new int[]{R.id.music_title};
       
        SimpleCursorAdapter adapter =
            new SimpleCursorAdapter(this,R.layout.file_list_row, mCursor, from ,to);
       
        mFilelist.setAdapter(adapter);
        mFilelist.setOnItemClickListener(new OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                mCursor.moveToPosition(position);
                String url = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                String urlPlaying = mProxy.getDataSource();
               
                if(urlPlaying == null || url.compareTo(urlPlaying)!=0){
                    //如果是第一次播放或不是同一首歌
                    mProxy.setDataSource(url);  
                    mProxy.start();
                }else{
                    if(mProxy.isPlaying()){
                        mProxy.pause();
                    }else{
                        mProxy.resume();
                    }
                }
            }
        });
    }

    @Override
    protected void onPause() {
        if(!mProxy.isPlaying()){
            mProxy.stopService();
        }
        super.onPause();
    }
}