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