I'm trying to update music player SeekBar in service, but nothing happens. The service start ok in my activity and bind correctly (because I can use some of the methods in my service and music play fine). Here is my service code:
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);
}
}
Interesting part is, after binding the service to my activity and run it some methods of the service returning null value like getDuration()
and some of them work find like onStart()
and onDestroy()
.
Thanks in advance.
Update:
In your activity you have to check if the service bound because it take a while to do, then use the public methods that it provide like:
//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;
}
};
and keep in mind that the onCreate()
method of services run first and one time.
You shouldn't update the UI directly from your Service
class, this is not its responsibility.
In your Activity
you can run a CountDownTimer
or similar to periodically poll your Service
to handle SeekBar
updates.
If you need to send messages from your Service to your Activity (such as when the track is finished, etc.) you can use a LocalBroadcastManager
Some examples:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With