简体   繁体   中英

How do I know if a sound is finished playing in android?

How do I know if a sound has finished playing?

I want to play 2 sounds but I want one sound to play and then wait until the 1st sound is done before the 2nd starts.

Also, if I wanted to do something else when the sound is finished like show he next view in a view flipper, could I do that?

Right now I'm using SoundPool to play my sounds.

使用MediaPlayer类和OnCompletionListener

Just an idea... get ogg/wav sound play time length and use your own SoundObject class with timer member. Update it in some update function. If timer > maxtime + threshold, flag it as finished.

The way I solved this is to create an animation sequence that contains an image, a sound, and a delay. I can then queue these up so I can have a image shown, and sound accompany it, and then switch to another image. I do this with a SoundPlayer and a custom view (not a view flipper, though you probably could)

The trick is that you can't simply pause the thread for the delay, you'll need to use a handler to send yourself a message to update the UI in the future.

Here is the Handler

handler = new Handler() {

            /* (non-Javadoc)
             * @see android.os.Handler#handleMessage(android.os.Message)
             */
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == NEXT_ITEM_MSG) {
                    showNext();
                }
                else if (msg.what == SEQUENCE_COMPLETE_MSG) {
                    // notify the listener
                    if (animationCompleteListener != null) {
                        animationCompleteListener.onAnimationComplete();
                    }
                }
            }
        };

The showNext() method simply grabs the next item in the sequence, updates the image view, plays the sound, and then schedules a message for the handler to call showNext after the sequence.

private void showNext() {
        if (mRunning) {
            // Get the first item
            AnimatedSequenceItem item = currentSequence.getNextSequenceItem();
            if (item == null) {
                Message msg = handler.obtainMessage(SEQUENCE_COMPLETE_MSG);
                handler.sendMessage(msg);
                return;
            }
            // Show the first image
            showImage(item.getImageResId());
            // Play the sound
            int iSoundResId = item.getSoundResId();
            if (iSoundResId != -1) {
                playSound(iSoundResId);
            }

            // schedule a message to advance to next item after duration
            Message msg = handler.obtainMessage(NEXT_ITEM_MSG);
            handler.sendMessageDelayed(msg, item.getDuration());
        }
    }

Of course all of this does require you to determine and hardcode the delays, but in my experience you need to do that for a game anyway. I had many cases where I wanted the delay to be longer than the sound. Here's the code that actually queues up items.

battleSequence.addSequenceItem(R.drawable.brigands, 
                   R.raw.beep, 
                   2000);
battleSequence.addSequenceItem(R.drawable.black,
                               winning ? R.raw.enemy_hit : R.raw.player_hit, 
                               1500);

With this approach I can have all sorts of logic to add animation items, change durations, loop animations, etc... It just took some fine tuning to get the delays right.

Hope this helps.

Sorry this is too late to reply. But i used isPlaying() API from mediaplayer to wait for first song to complete.

while(mediaPlyaer.isPlaying()){
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM