2013-06-22 10 views
5

Próbuję zaktualizować odtwarzacz muzyczny SeekBar w serwisie, ale nic się nie dzieje. Usługa zaczyna działać poprawnie i jest prawidłowo powiązana (ponieważ mogę korzystać z niektórych metod w mojej usłudze i grać dobrze w muzyce). Oto mój kod usługi:Zaktualizuj MusicPlayer SeekBar w usłudze

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); 
} 

} 

Ciekawe jest to, po związaniu usługę do mojej działalności i uruchomienia go kilka metod służby powrocie wartość null jak getDuration() a niektóre z nich działają znaleźć jak onStart() i onDestroy().

Z góry dziękuję.

Aktualizacja:

W swojej działalności trzeba sprawdzić, czy usługa związana bo to potrwać do zrobienia, a następnie użyć metody publiczne, które to zapewniają jak:

//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; 
    } 
}; 

i zachować biorąc pod uwagę, że metoda usług onCreate() jest uruchamiana jako pierwsza i jednorazowa.

Odpowiedz

3

Nie należy aktualizować interfejsu użytkownika bezpośrednio z klasy Service, nie jest to jego obowiązkiem.

W swoim można uruchomić urządzenie CountDownTimer lub podobne, aby okresowo odpytywać swój numer Service, aby obsłużyć aktualizacje SeekBar.

Jeśli chcesz wysyłać wiadomości z Twojego serwisu na swojej działalności (na przykład, gdy utwór jest gotowy, itd.) Można użyć LocalBroadcastManager

kilka przykładów:

+0

Dzięki za odpowiedź Kena Wolfa, ale dlaczego nie mogę uzyskać czasu trwania odtwarzacza muzycznego, dzwoniąc do serwisu? – Sozi

+0

Mówisz, że zwraca wartość null, ale czy masz na myśli, że zwraca 0? –

+0

W mojej aktywności po powiązaniu i uruchomieniu usługi przy próbie uzyskania danych z usługi, takich jak "Integer duration = myMediaPlayer.getDuration();" (myMediaPlayer jest obiektem mojej klasy usług) generuje "wyjątek NullPointerException". – Sozi