在Android中单击按钮时如何播放声音?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2753943/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:13:51  来源:igfitidea点击:

How to Play sound when button is clicked in Android?

android

提问by Grendizer

I'm trying to play a sound file when a button is clicked but keeps getting an error.

我试图在单击按钮时播放声音文件,但一直出现错误。

The error is:

错误是:

 "The method create(Context, int) in the type MediaPlayer is not applicable for the arguments (new View.OnClickListener(){}, int)"

Here's my code:

这是我的代码:

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    Button zero = (Button)this.findViewById(R.id.btnZero);
    zero.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mp = MediaPlayer.create(this, R.raw.mamacita_zero);
        }
    });
}

Any help or tips would be appreciated. Thnx!

任何帮助或提示将不胜感激。谢谢!

回答by pablo.meier

There are a few things going on here (disclaimer, this is just how I'm used to using it, there may be a better way):

这里发生了一些事情(免责声明,这只是我习惯使用它的方式,可能有更好的方法):

  • You seem to be doing a lot more work per click than you need to. You're creating and adding a new onClickListenerfor every click in the Activity's View, not the Button. You only need to set the listener once, and for the Button rather than the overarching View; I tend to do that in the constructor of the Activity.

  • Regarding your error, MediaPlayer works fine for me when the Context I pass it is the overriding Activity. When you pass this, it's passing the onClickListeneryou are creating, throwing off the MediaPlayer.

  • Finally, to actually play the sound, you have to call start().

  • 您每次点击所做的工作似乎比您需要的要多得多。您正在onClickListenerActivity 的 View 中的每次点击创建和添加一个新的,而不是 Button。您只需要设置一次监听器,并且是为 Button 而不是总体视图;我倾向于在 Activity 的构造函数中这样做。

  • 关于您的错误,当我传递的上下文是覆盖活动时,MediaPlayer 对我来说很好用。当您通过 时this,它会通过onClickListener您正在创建的 ,从而抛弃 MediaPlayer。

  • 最后,要真正播放声音,您必须调用start().

So for the constructor in the Activity, you can create the MediaPlayeronce, find the Button, and attach an onClickListenerthat will play the sound from the MediaPlayer you've just created. It would look something like:

因此,对于 Activity 中的构造函数,您可以创建MediaPlayer一次,找到 Button,并附加一个onClickListener将从您刚刚创建的 MediaPlayer 播放声音的对象。它看起来像:

public class MyActivity extends Activity {

    public MyActivity(Bundle onSavedStateInstance) {
        // eliding some bookkeepping

        MediaPlayer mp = MediaPlayer.create(this, R.raw.mamacita_zero);

        Button zero = (Button)this.findViewById(R.id.btnZero);
        zero.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mp.start();
            }
        });
    }
}

Hope that helps!

希望有帮助!

回答by Jan Sindberg

I have played around with media-player, and it is easy to get in trouble. I followed the advice of Volodymyr, and SoundPool is much easier to manage.

我玩过媒体播放器,很容易遇到麻烦。我听从了 Volodymyr 的建议,SoundPool 更容易管理。

MediaPlayer does not like to play more than one sound at the time, like for instance when you have lots of quick tabs on your buttons. I managed with the following method:

MediaPlayer 不喜欢同时播放多个声音,例如当您的按钮上有很多快速选项卡时。我用以下方法管理:

private void playSound(Uri uri) {
    try {
        mMediaPlayer.reset();
        mMediaPlayer.setDataSource(this, uri);
        mMediaPlayer.prepare();
        mMediaPlayer.start();
    } catch (Exception e) {
        // don't care
    }

}

}

In the constructor I did:

在构造函数中我做了:

mMediaPlayer = new MediaPlayer();
mSoundLess = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.less);
mSoundMore = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.more);

On click I would then call playSound(mSoundLess):

点击后我会打电话 playSound(mSoundLess):

Instead I have created a SoundPool helper:

相反,我创建了一个 SoundPool 助手:

package com.mycompany.myapp.util;

import java.util.HashSet;
import java.util.Set;

import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;

public class SoundPoolHelper extends SoundPool {
    private Set<Integer> mLoaded;
    private Context mContext;

    public SoundPoolHelper(int maxStreams, Context context) {
        this(maxStreams, AudioManager.STREAM_MUSIC, 0, context);
    }

    public SoundPoolHelper(int maxStreams, int streamType, int srcQuality, Context context) {
        super(maxStreams, streamType, srcQuality);
        mContext = context;
        mLoaded = new HashSet<Integer>();
        setOnLoadCompleteListener(new OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                mLoaded.add(sampleId);
            }
        });
    }

    public void play(int soundID) {
        AudioManager audioManager = (AudioManager) mContext.getSystemService( Context.AUDIO_SERVICE);
        float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        float volume = actualVolume / maxVolume;
        // Is the sound loaded already?
        if (mLoaded.contains(soundID)) {
            play(soundID, volume, volume, 1, 0, 1f);
        }
    }
}

Now I init like this:

现在我这样初始化:

mSoundPoolHelper = new SoundPoolHelper(1, this);
mSoundLessId = mSoundPoolHelper.load(this, R.raw.less, 1);
mSoundMoreId = mSoundPoolHelper.load(this, R.raw.more, 1);

and play a sound like this:

并播放这样的声音:

private void playSound(int soundId) {
    mSoundPoolHelper.play(soundId);
}

Don't forget to call mSoundPoolHelper.release();, for instance in your onDestroy(). Something similar is needed if you use MediaPlayer.

不要忘记调用mSoundPoolHelper.release();,例如在您的onDestroy(). 如果您使用 MediaPlayer,则需要类似的东西。

回答by Boris Karloff

MediaPlayer mp = MediaPlayer.create(getBaseContext(),
R.raw.yoursoundfile);
mp.start();

the file yoursoundfile must to be in the res/raw folder

yoursoundfile 文件必须在 res/raw 文件夹中

回答by Gagan Deep

If you really have to invoke the click programmatically because the view has no own sound, i would solve it like that, its the simplest solution and a oneliner

如果你真的必须以编程方式调用点击,因为视图没有自己的声音,我会这样解决,它是最简单的解决方案和一个单线

view.playSoundEffect(SoundEffectConstants.CLICK);

very simple and works, if you want to make a layout play a sound you need to put

非常简单且有效,如果您想让布局播放声音,则需要放置

android:soundEffectsEnabled="true"

in your xml.

在你的 xml 中。