Android音频搜索栏延迟

时间:2016-10-13 21:30:26

标签: java android android-mediaplayer android-seekbar

刚开始学习Java,我正在学习一些基于媒体的东西。 我创建了一个小应用程序(播放音乐文件)与音量控制器搜索栏工作正常,播放和停止按钮,也工作正常。当音乐播放时,我设法直到这一点,进展寻找条形更新并在播放歌曲时需要做的向右移动。当想要添加代码以实际上能够改变音乐的进度时,每次更新搜索时都会得到一个暂停(延迟)(每1000毫秒/ 1秒)。如果我添加

mplayer.seekTo(progress);

代码,每次搜索栏更新(每秒)都会得到音乐延迟。

这是我的代码:

package com.dionisie.sounddemo;

import android.content.Context; import android.media.AudioManager;
import android.support.v7.app.AppCompatActivity; import
android.os.Bundle; import android.media.MediaPlayer; import
android.view.View; import android.widget.SeekBar; import
android.widget.SeekBar.OnSeekBarChangeListener; import
android.util.Log;

import java.util.Timer; import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {

    MediaPlayer mplayer;

    AudioManager audioManager;

    public void playAudio(View view) {
        mplayer.start();
    }


    public void pauseAudio(View view) {
        mplayer.pause();
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mplayer = MediaPlayer.create(this, R.raw.joanna);

        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        int curVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

        SeekBar volumeControl = (SeekBar) findViewById(R.id.seekBar);
        volumeControl.setMax(maxVolume);
        volumeControl.setProgress(curVolume);

        volumeControl.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                audioManager.setStreamVolume(audioManager.STREAM_MUSIC, progress, 0);

            }
        });


        final SeekBar scrubber = (SeekBar) findViewById(R.id.scrubber);

        scrubber.setMax(mplayer.getDuration());

        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                scrubber.setProgress(mplayer.getCurrentPosition());
            }
        }, 0, 1000);

        scrubber.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                mplayer.seekTo(progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

    } }

3 个答案:

答案 0 :(得分:0)

首先,定义一个public int和一个公共布尔int save, boolean flag

将您的setOnSeekBarChangeListener更改为此

 volumeControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            save = progress;

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            mplayer.pause();
            flag = true;


        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mplayer.seekTo(save);
            mplayer.start();
        }
    });

然后将Timer().scheduleAtFixedRate更改为此(添加if语句)

new Timer().scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {

            if (!flag) 
                scrubber.setProgress(mplayer.getCurrentPosition());

        }
    },0 ,1000);

并完成! 希望了解改变的原因。但如果你没有问过。

答案 1 :(得分:0)

函数“ setProgress”在“搜索”栏中进行了更改,计时器每x毫秒调用一次。在搜索栏中进行的任何更改都将由“ seekbarchangeListener”捕获。在更改seekbarChangeListener中,我们添加了seekTo函数,该函数会将音乐移动x + dx秒。由于造成延迟效应的延迟,增加了额外的dx秒。

下面的实现检查isSongRunning布尔值,以便如果Timer的Seekbar中发生更改,则不会完成seekTo,如果由于seekbar中的移动而进行了更改,则将为false。

最终SeekBar sngbar =(SeekBar)findViewById(R.id.player);         sngbar.setMax(song.getDuration());

    new Timer().scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            isSongRunning = true;
            sngbar.setProgress(song.getCurrentPosition());

        }
    }, 0, 100);


    sngbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int sngchg, boolean b) {
            if(!isSongRunning){
                song.seekTo(sngchg);
            }else
            {
                isSongRunning = !isSongRunning;
            }

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });

此外,您可以将计时器中的x毫秒增加到10000,该延迟将非常小,并且很难识别。但是通过这种方式,搜索栏状态的反映将不会很快。

答案 2 :(得分:0)

onProgressChanged() 中, 将代码写成:

if(fromUser)
    mplayer.seekTo(progress);

因此,只有当用户这样做时,seekTo 才会被触发,而不是因为计时器。