11

这是播放媒体时更新 ProgressBar 的正确方法吗?我想在 MediaPlayer 中会有一个回调,但我找不到它。

mediaPlayer.start();
final SeekBar progress = (SeekBar) dialog.findViewById(R.id.seekBar1);
progress.setMax(mediaPlayer.getDuration());
new CountDownTimer(mediaPlayer.getDuration(), 250) {
  public void onTick(long millisUntilFinished) {
    progress.setProgress(progress.getProgress() + 250);
  }
  public void onFinish() {}
}.start();

最好的祝福。

4

3 回答 3

23

就个人而言,我开始一个线程,getCurrentPosition()每 200 毫秒左右检查一次,直到onCompletion()事件被触发:

private class MediaObserver implements Runnable {
  private AtomicBoolean stop = new AtomicBoolean(false);

  public void stop() {
    stop.set(true);
  }

  @Override
  public void run() {
    while (!stop.get()) {
      progress.setProgress(mediaPlayer.getCurrentPosition());
      Thread.sleep(200);
    }
  }
}

private MediaObserver observer = null;

public void runMedia() {
  mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener{
    @Override
    public void onCompletion(MediaPlayer mPlayer) {
      observer.stop();
      progress.setProgress(mPlayer.getCurrentPosition());
    }
  });
  observer = new MediaObserver();
  mediaPlayer.start();
  new Thread(observer).start();
}
于 2012-04-03T20:02:11.693 回答
11

看看android.widget.MediaController,它有一个进度条。

如果合适,他们使用递归调用自身的处理程序。您可以将延迟设置为您希望更新进度条的频率。

请注意,控制器可以显示或隐藏,也可以由用户拖动,当然,视频可以停止。这些是!mDragging && mShowing && mVideoView.isPlaying()在另一个递归调用更新栏之前进行各种检查 ( ) 的原因。

protected Handler mHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        int pos;
        switch (msg.what)
        {
            // ...

            case SHOW_PROGRESS:
                pos = setProgress();
                if (!mDragging && mShowing && mVideoView.isPlaying())
                {
                    msg = obtainMessage(SHOW_PROGRESS);
                    sendMessageDelayed(msg, 1000 - (pos % 1000));
                }
                break;

             // ...
        }
    }
};

要开始使用:

mHandler.sendEmptyMessage(SHOW_PROGRESS);

它会自行停止,但您应该使用以下命令取消最后一个待处理的请求:

mHandler.removeMessages(SHOW_PROGRESS);
于 2012-04-03T20:39:51.017 回答
3

最有效的方法是使用 JRaymond 的答案和EventBus

private class MediaObserver implements Runnable {
    private AtomicBoolean stop = new AtomicBoolean(false);
    public void stop() {
        stop.set(true);
    }

    @Override public void run() {
        while (!stop.get()) {
            try {
              if (player.isPlaying())
                 sendMsgToUI(player.getCurrentPosition(),
                             player.getDuration());
            } catch (Exception e){e.printStackTrace();}
            try { 
              Thread.sleep(100);
            } catch (InterruptedException e) { e.printStackTrace(); }
        }
    }
}

private MediaObserver observer = null;

public void runMedia() {
    observer = new MediaObserver();
    new Thread(observer).start();
}

//handles all the background threads things for you
private void sendMsgToUI(int position) {
    ChangingEvent event = new ChangingEvent(position);
    EventBus.getDefault().post(event);
}

ChangeEvent 类看起来像这样:

public class ChangingEvent {
  private int position;

  public ChangingEvent(int position) {
      this.position= position;
  }

  public int getPosition() {
      return position;
  }
}

在您的活动或片段中,您所要做的就是

class YouClass extends Activity {
  private EventBus eventBus = EventBus.getDefault();
}

@Override protected void onCreate(Bundle savedInstanceState) {
    //your code
    eventBus.register(this);
}
//eventbus that updates UI
public void onEventMainThread(ChangingEvent event) {
    //seekbar or any other ui element
    seekBar.setProgress(event.getPosition());
}
于 2015-07-13T09:16:40.110 回答