android - 更新服务中的 MusicPlayer SeekBar

标签 android service seekbar audio-player android-music-player

我正在尝试更新服务中的音乐播放器 SeekBar,但没有任何反应。该服务在我的 Activity 中正常启动并正确绑定(bind)(因为我可以在我的服务中使用某些方法并且音乐播放正常)。这是我的服务代码:

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

}

有趣的是,在将服务绑定(bind)到我的 Activity 并运行它之后,服务的一些方法返回空值,如 getDuration(),其中一些方法可以找到,如 onStart()onDestroy()

提前致谢。

更新:

在您的 Activity 中,您必须检查服务是否绑定(bind),因为这需要一段时间才能完成,然后使用它提供的公共(public)方法,例如:

//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() 方法会先运行一次。

最佳答案

您不应该直接从您的 Service 类更新 UI,这不是它的责任。

在您的Activity 中,您可以运行一个CountDownTimer 或类似的工具来定期轮询您的Service 以处理SeekBar 更新.

如果您需要从您的服务向您的 Activity 发送消息(例如轨道结束时等),您可以使用 LocalBroadcastManager

一些例子:

关于android - 更新服务中的 MusicPlayer SeekBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17247715/

相关文章:

android - WifiP2pDnsSdServiceInfo.newInstance 中的可用服务类型

Android - 设置搜索栏进度始终留给拇指

java - 使用未知人士的外部库有哪些风险?可能是恶意软件吗?

java - Android Studio 项目中的 NoSuchFieldError

javascript - 如何从第二个 Web View 访问我的应用程序的 ionic 存储 (localForage)?

带有流式音频的 Android 搜索栏

Android - 如何通过调用 seekbar 方法来定义值?

android - 如何更改操作栏的颜色(actionbarsherlock)

sql - SSIS部署: The task <task name> cannot run on this edition of integration services.需要更高级别的版本

android - 如何循环服务?