Android 媒体播放器、进度条
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10000400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MediaPlayer, ProgressBar
提问by pouzzler
Is this the correct way to update a ProgressBar when playing Media? I figured there would be a callback in MediaPlayer, but I couldn't find it.
这是在播放媒体时更新 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();
Best regards.
此致。
回答by JRaymond
Personally, I start off a Thread that checks getCurrentPosition()
every 200ms or so until the onCompletion()
event gets fired off:
就个人而言,我开始一个线程,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();
}
回答by Peter Ajtai
Take a look at android.widget.MediaController, it has a progress bar.
看看android.widget.MediaController,它有一个进度条。
They use a handler that recursively calls itself if appropriate. You can set the delay to however often you want the progress bar updated.
如果合适,它们使用递归调用自身的处理程序。您可以将延迟设置为您希望进度条更新的频率。
Note that the controller can be shown or hidden as well as dragged by the user, and - of course - the video can stop. These are the reasons for the various checks (!mDragging && mShowing && mVideoView.isPlaying()
) before another recursive call to update the bar.
请注意,控制器可以显示或隐藏以及由用户拖动,当然 - 视频可以停止。这些是!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;
// ...
}
}
};
To start it off use:
要开始使用:
mHandler.sendEmptyMessage(SHOW_PROGRESS);
It will stop by itself, but you should cancel the last pending request using:
它会自行停止,但您应该使用以下命令取消最后一个挂起的请求:
mHandler.removeMessages(SHOW_PROGRESS);
回答by Fedor Tsyganov
The most efficient way is to use JRaymond's answer and EventBus
最有效的方法是使用 JRaymond's answer 和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);
}
ChangingEvent class would look something like that:
ChangedEvent 类看起来像这样:
public class ChangingEvent {
private int position;
public ChangingEvent(int position) {
this.position= position;
}
public int getPosition() {
return position;
}
}
and in your Activity or Fragment all you have to do is
在您的 Activity 或 Fragment 中,您所要做的就是
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());
}