web-dev-qa-db-ja.com

MediaPlayer、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();

宜しくお願いします。

11
pouzzler

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);
11
Peter Ajtai

個人的には、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();
}
22
JRaymond

最も効率的な方法は、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);
}

ChangesEventクラスは次のようになります。

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());
}
3
Fedor Tsyganov