定时器中断MediaPlayer

时间:2013-04-30 19:48:31

标签: android

在我的活动中有一个计时器,它每隔一秒向处理程序发送一条消息,用于更改图片。

每次用户点击图像时,都会使用以下代码在活动的onClickListner函数中播放声音:

MediaPlayer.create(this, R.raw.voice).start();

在xperia arc(Android 4.0.4)上,声音未完全播放,一旦定时器触发,它就会停止。如果我禁用计时器,则没有问题。

在HTC Legend(Android 2.2)上没有问题。声音完全播放。

我无法弄清楚问题。

public class ActivityTest extends Activity implements View.OnClickListener, ViewSwitcher.ViewFactory
{

    ImageSwitcher switcher;

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_listen);

        switcher = (ImageSwitcher) findViewById(R.id.imageSwitcher);
        switcher.setFactory(this);
        switcher.setOnClickListener(this);

        final Handler handler = new Handler()
        {
            @Override
            public void handleMessage(Message msg)
            {
                switcher.setImageDrawable(getResources().getDrawable(R.drawable.image));
                // if this line is commented it works fine
            }
        };

        new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run()
            {
                handler.sendEmptyMessage(0);
            }
        }, 0, 1000);
    }

    @Override
    public void onClick(View view)
    {
        MediaPlayer.create(this, R.raw.voice).start();
    }


    @Override
    public View makeView()
    {
        ImageView image = new ImageView(this);
        image.setScaleType(ImageView.ScaleType.FIT_CENTER);
        image.setLayoutParams(new ImageSwitcher.LayoutParams(ImageSwitcher.LayoutParams.FILL_PARENT, ImageSwitcher.LayoutParams.FILL_PARENT));
        return image;
    }
}

解决方案-------------------------------------

我将MediaPlayer的声明移到了课堂上,它解决了这个问题。

    MediaPlayer mp;
    @Override
    public void onClick(View view)
    {
        mp =MediaPlayer.create(this, R.raw.voice);
        mp.start();
    }

我不知道为什么以前的代码适用于2.2而不是4.无论如何它都有效。

1 个答案:

答案 0 :(得分:1)

因为它的声音很短,所以我推荐一个音池。 Soundpool剪辑保存在内存中以便快速访问,因为它很小。我假设你演的声音很短。在onCreate中执行此操作以预加载它:

// Load the sound
    soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
 soundID= soundPool.load(this, R.raw.voice, 1);

  soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int sampleId,
                int status) {
            loaded = true;
        }
    });

然后在onclick方法中(当用户点击图像时)执行以下操作:

AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
            float actualVolume = (float) audioManager
                    .getStreamVolume(AudioManager.STREAM_MUSIC);
            float maxVolume = (float) audioManager
                    .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            float volume = actualVolume / maxVolume;

            if (loaded) {
                soundPool.play(soundID, volume, volume, 1, 0, 1f);
}

其中soundPool被声明为实例变量private SoundPool soundPool或类似的东西。试试看,让我知道会发生什么。