如何从服务中的 MediaPlayer 运行 更新 SeekBar?

How to update SeekBar from MediaPlayer running in Service?

在我的应用程序中,我维护了一个从服务播放的 MediaPlayer,以更新 SeekBar 我在 Service

中完成了一个定时器任务
timer = new Timer();
timer.scheduleAtFixedRate(new RemindTask(), 0, 1 * 1000);

class RemindTask extends TimerTask {
    @Override
    public void run() {
        if (mediaPlayer!=null && mediaPlayer.isPlaying()){
           MusicPlayerActivity.progress=mediaPlayer.getCurrentPosition();
           MusicPlayerActivity.total=mediaPlayer.getDuration();
        }
    }
}

并使用 运行 可用列表,我在 activity 页面中创建了一个 运行 方法,

@Override
public void run()
{
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            seekBar.setMax(total);
            seekBar.setProgress(progress);
        }
    });
}

但我的问题是应用程序非常慢并且卡住了。

使用 BroadcastReceiver 将搜索栏表单服务更新为 activity

在 activity 中添加广播以更新您的搜索栏

BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //do something based on the intent's action
            // UPDATE YOUR UI FROM HERE
        }
    };

在 activity 中注册接收器,如下所示

@Override
    protected void onResume() {
        super.onResume();
        registerReceiver(receiver, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }

从您的服务发送广播 -> 在您的服务中添加以下代码以调用广播

Intent intent = new Intent();
intent.setAction("android.mybroadcast");
this.context.sendBroadcast(intent);

在 intent 中传递数据 -> seek-bar 的整数值 :)

投入使用以更新查找变量(全局和静态变量)的值

     private final Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg){


      //  update the seek variable here
        }
    };

在你的activity中:

        PlayerConstants.PROGRESSBAR_HANDLER = new Handler(){
             @Override
              public void handleMessage(Message msg){
//get seek bar variable value and set to progress bar
}
        };
     }catch(Exception e){}

如果您需要 activity 通信服务,请使用绑定服务 check it here. Or use libraries like EventBus

您可以在 https://github.com/googlesamples/android-UniversalMusicPlayer/blob/master/mobile/src/main/java/com/example/android/uamp/ui/FullScreenPlayerActivity.java 中的 android-UniversalMusicPlayer 参考实现中找到可行的解决方案。

这个概念涉及在 MediaSession 实例上设置当前位置,然后轮询 MediaController 以获取更改 + 计算当前位置:

private void updateProgress() {
    if (mLastPlaybackState == null) {
        return;
    }
    long currentPosition = mLastPlaybackState.getPosition();
    if (mLastPlaybackState.getState() != PlaybackState.STATE_PAUSED) {
        // Calculate the elapsed time between the last position update and now and unless
        // paused, we can assume (delta * speed) + current position is approximately the
        // latest position. This ensure that we do not repeatedly call the getPlaybackState()
        // on MediaController.
        long timeDelta = SystemClock.elapsedRealtime() -
                mLastPlaybackState.getLastPositionUpdateTime();
        currentPosition += (int) timeDelta * mLastPlaybackState.getPlaybackSpeed();
    }
    mSeekbar.setProgress((int) currentPosition);
}