2013-06-22 26 views
5

我想更新服務的音樂播放器搜索欄,但沒有任何反應。該服務在我的活動中正常啓動並正確綁定(因爲我可以使用我的服務中的某些方法並且音樂播放正常)。這裏是我的服務代碼:更新MusicPlayer搜索欄在服務

public class MusicPlayerService extends Service { 

MediaPlayer myMusicPlayer; 
String path; 
Intent getMusicId = new Intent(); 

// Binder given to clients 
private final IBinder mBinder = new LocalBinder(); 

/** 
* Class used for the client Binder. Because we know this service always 
* runs in the same process as its clients, we don't need to deal with IPC. 
*/ 
public class LocalBinder extends Binder { 
    MusicPlayerService getService() { 
     // Return this instance of LocalService so clients can call public methods 
     return MusicPlayerService.this; 
    } 
} 


@Override 
public void onCreate() { 
    // TODO Auto-generated method stub 
    myMusicPlayer = new MediaPlayer(); 
    Log.d(getClass().getSimpleName(),"onCreate()"); 
    super.onCreate(); 
} 

@Override 
public void onDestroy() { 
    // TODO Auto-generated method stub 
    super.onDestroy(); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    // TODO Auto-generated method stub 

    Log.d(getClass().getSimpleName(), "onStartCommand()"); 

    return super.onStartCommand(intent, flags, startId); 
} 

@Override 
public IBinder onBind(Intent intent) { 
    path = intent.getStringExtra("musicID"); 

    Log.e("Music path on SD received from intent", path); 

    try { 
     myMusicPlayer.setDataSource(path); 
     myMusicPlayer.setLooping(true); 
     myMusicPlayer.prepare(); 
    } catch (IllegalArgumentException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (SecurityException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IllegalStateException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    myMusicPlayer.start(); 

    Log.d(getClass().getSimpleName(), "onBind()"); 

    return mBinder; 
} 

/** method for clients */ 
public int getMusicDuration() { 
    return myMusicPlayer.getDuration(); 
} 

public int getMusicCurPos(){ 
    return myMusicPlayer.getCurrentPosition(); 
} 

public void pauseMusic(){ 
    myMusicPlayer.pause(); 
    Log.d(getClass().getSimpleName(), "pauseMusic()"); 
} 

public void playMusic(){ 
    myMusicPlayer.start(); 
    Log.d(getClass().getSimpleName(), "start()"); 
} 
public void stopMusic(){ 
    myMusicPlayer.stop(); 
    Log.d(getClass().getSimpleName(), "stop()"); 
} 
public void seekToPos (int pos){ 
    myMusicPlayer.seekTo(pos); 
} 

} 

有趣的是,該服務綁定到我的活動和運行的服務的一些方法返回空值像getDuration(),其中有些工作找到像onStart()onDestroy()後。

在此先感謝。

更新:

在你的活動,你必須檢查約束,因爲它的服務需要一段時間才能做,然後用公共的方法,它提供諸如:

//Bound Music service and pass the music path 
    Intent musicIntent = new Intent(this, MusicPlayerService.class); 
    musicIntent.putExtra("musicID", path); //Put Extra data for music player to play the exact file 
    bindService(musicIntent, mConnection, Context.BIND_AUTO_CREATE); //Bound the Music player service 

    //Music Handler for methods 
    musicMethodsHandler = new Handler(); 
    musicRun = new Runnable() { 

     @Override 
     public void run() { 
      if (mBound == true){ // Check if service bounded 
       if (musicTotTime == null){ // Put data in it one time 
        musicTotTime = myMusicPlayer.getMusicDuration(); 
        Log.v("Music Duration of Player in thread", musicTotTime.toString()); 
        seekBar.setMax(musicTotTime); 
       } 
       musicCurTime = myMusicPlayer.getMusicCurPos(); 
       Log.v("Music Duration of Player in thread", musicCurTime.toString()); 
       seekBar.setProgress(musicCurTime); 
      }else if(mBound == false){ // if service is not bounded log it 
       Log.v("Still waiting to bound", Boolean.toString(mBound)); 
      } 
      musicMethodsHandler.postDelayed(this, 1000); 
     } 
    }; 
    musicMethodsHandler.postDelayed(musicRun, 1000); 


/** Defines callbacks for service binding, passed to bindService() */ 
private ServiceConnection mConnection = new ServiceConnection() { 

    @Override 
    public void onServiceConnected(ComponentName className, 
      IBinder service) { 
     // We've bound to LocalService, cast the IBinder and get LocalService instance 
     LocalBinder binder = (LocalBinder) service; 
     myMusicPlayer = binder.getService(); 
     mBound = true; 

    } 

    @Override 
    public void onServiceDisconnected(ComponentName arg0) { 
     mBound = false; 
    } 
}; 

,並保持記住onCreate()服務的方法是第一次和第一次運行。

回答

3

你不應該從你的Service類直接更新UI,這並不是它的責任。

在您的Activity中,您可以運行CountDownTimer或類似的程序,定期輪詢Service以處理SeekBar更新。

如果您需要發送您的服務信息到你的活動(在賽道結束,等如),你可以使用LocalBroadcastManager

一些例子:

+0

感謝您的答覆肯·沃爾夫,但爲什麼我不能調用服務方法獲取音樂播放時長? – Sozi

+0

你說它返回null,但是你的意思是它返回0嗎? –

+0

在綁定和啓動服務時,試圖從服務中獲得的數據等之後,我的活動「整數持續時間= myMediaPlayer.getDuration();」 (myMediaPlayer是我的服務類的一個對象),它會拋出一個「NullPointerException」。 – Sozi