I want to play a short sound when a button is clicked using SoundPool. But when the button is clicked no sound appears despite the Log telling me it's loaded and "playing". The soundfile is an .ogg in case that's relevant. Here's my code, buttonSound() is called in onCreate().
void buttonSound(){
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
soundPool = new SoundPool.Builder().setAudioAttributes(attributes).build();
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
Log.d("SOUNDPOOL", "COMPLETE "+button);
}
});
button = soundPool.load(this, R.raw.button, 1);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.button_back:
// Sound loaded
if(button != 0) {
soundPool.play(button, 1f, 1f, 1, 0, 1f);
Log.d("PLAYING", "PLAYING");
}
break;
So apparently AudioAttributes.USAGE_ASSISTANCE_SONIFICATION was the issue, it works fine with AudioAttributes.USAGE_GAME and AudioAttributes.USAGE_MEDIA. I have no idea why, though.
Related
I am trying to play a sound in an app. However, using SoundPool I am unable to do so. The code is really simple and I don't see where it can fail.
A similar code but using MediaPlayer does work, but I am interested in using SoundPool.
SoundPool code:
private void playSound2(){
SoundPool sp = new SoundPool.Builder().build();
int soundID = sp.load(MainActivity.this, R.raw.sound, 1);
sp.play(soundID, 1, 1, 1, 0, 1);
}
Context:
public void goButtonClick(View view){
Button goButton = findViewById(id.button2);
if (onGoing){
goButton.setText("GO!");
} else {
goButton.setText("STOP");
//playSound(); // MediaPlayer
playSound2(); // SoundPool
}
onGoing = !onGoing;
}
MediaPlayer version (works):
private void playSound(){
MediaPlayer mediaPlayer;
mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sound);
mediaPlayer.start();
}
Solved!
I was missing to wait for the loading of the sound file into soundPool. The correct code is:
private void playSound2() {
SoundPool sp = new SoundPool.Builder().build();
int soundID = sp.load(MainActivity.this, raw.sound, 1);
sp.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool sp, int soundID, int i1) {
sp.play(soundID, 1, 1, 1, 0, 1);
}
});
}
I have one SoundPool in my Android app, but I don't know how to write code for 2 or more SoundPool instances. Is there a way to rework this code for multiple SoundPools?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = findViewById(R.id.button1);
view.setOnTouchListener(this);
// Set the hardware buttons to control the music
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener()
{
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
soundID = soundPool.load(this, R.raw.sound1, 1);
}
public boolean onTouch( View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Getting the user sound settings
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;
// Is the sound loaded already?
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
Log.e("Test", "Played sound");
}
}
return false;
}
Try:
// 8 soundpools
SoundPool[] soundPool = new SoundPool[8];
int[] soundID = new int[8];
// You can have more that one set per sound if need, just make more raw sound
// arrays with different sounds.
// 8 sounds per soundpool
int[] rawSounds = new int[]{ R.id.sound1, R.id.sound2, R.id.sound3,
R.id.sound4, R.id.sound5, R.id.sound6,
R.id.sound7, R.id.sound8 };
boolean[] loaded = new boolean[8];
// Go through each soundpool
for(int i = 0; i < 8; i++)
{
soundPool[i] = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
// 8 sounds in one soundpool
for(int h = 0; h < 8; h++)
{
soundID[i] = soundPool.load(this, rawSounds[i], 1);
}
soundPool[i].setOnLoadCompleteListener(new OnLoadCompleteListener()
{
Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status)
{
// One boolean per soundpool
loaded[i] = true;
}
});
}
Then use a for loop to see what is being press for which sound and use soundID[i].play to play sounds.
Hope this helps even though a little late!)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = findViewById(R.id.textView1);
view.setOnTouchListener(this);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
soundID = soundPool.load(this, R.raw.dog_bark, 1);
}
;
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
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);
}
}
return false;
}
}
I tried this way, but the sound is being played on touch event. I want the sound to be played automatically when my activity starts. But it should stop after a loop is completed and start again on touch event. Please help.
Use this in the activity where you wanna hear the music
mMediaPlayer = new MediaPlayer();
mMediaPlayer = MediaPlayer.create(this, R.raw.sound1);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setLooping(true);
mMediaPlayer.start();
public class CommonMethod {
public static MediaPlayer player;
public static void SoundPlayer(Context ctx,int raw_id){
player = MediaPlayer.create(ctx, raw_id);
player.setLooping(false); // Set looping
player.setVolume(100, 100);
//player.release();
player.start();
}
}
//you can use this method for stopping the player.
CommonMethod.player.stop();
If it because you are just loading the sound on onCreate() and play it on touch!
Try soundPlay.play() in onCreate instead!
you can play the sound in a runnable and post it in onCreate method.
View view = findViewById(R.id.textView1);
view.post(new Runnable() {
#Override
public void run() {
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
}
}
});
Put your onTouch() method's code into OnStart() method of your Activity, so that when activity is started, then Your sound plays.
If your activity name is MainActivity
MediaPlayer play= MediaPlayer.create(MainActivity.this,R.raw.sound);
play.start();
Place this in the onCreate method
In my activity there is a timer which send a message to a handler every second which changes a picture.
Every time user clicks the image a sound is played in onClickListner function of activity using this code:
MediaPlayer.create(this, R.raw.voice).start();
On a xperia arc (Android 4.0.4) the sound is not completely played and as soon as the timer triggers it stops. If I disable the timer there is no problem.
On a HTC Legend (Android 2.2) there is no problem. The sound is played completely.
I can't figure out the problem.
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;
}
}
Solution -------------------------------------
I moved the declaration of MediaPlayer to class and it fixed the problem.
MediaPlayer mp;
#Override
public void onClick(View view)
{
mp =MediaPlayer.create(this, R.raw.voice);
mp.start();
}
I don't know why the previous code works on 2.2 but not 4. anyway it worked.
since its a short sound your playing i'd recommend a soundpool. Soundpool clips are kept in memory for quick access since there small. Im assuming your playing a very short sound. in onCreate do this to preload it:
// 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;
}
});
then in the onclick method (when user clicks the image) do this:
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);
}
where soundPool is declared as a instance variable private SoundPool soundPool or something similar. Try that and let me know what happens.
I have a sound clip play while I am displaying some numbers, then want it to stop. Then I want to repeat the process.
init stuff:
private SoundPool soundPool;
private int soundRoll;
boolean soundloaded = false;
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundloaded = true;
}
});
soundRoll = soundPool.load(this, R.raw.roll, 1);
Thread Call:
public void update() {
.......
new Thread(new Runnable() {
public void run() {
int streamID = 0;
streamID = soundPool.play(soundRoll, volume, volume, 1, -1, 1);
... loop to animate text....
soundPool.stop(streamID);
}
}).start();
}
This works fine every other time.
so the first time it plays and stops at the right time.
second time I hear nothing
but then it works the third time
If I take out the looping, then it works.
Any help would be appretiated
Seems that if I switch to an OGG file from an MP3, the bug goes away