I'm trying to make a soundboard app, but I'm running into a problem with handling the sound files. More specifically I do not know how to get it so when a button is pressed it plays a corresponding sound back.
I've tried using this way
Play sound on button click android
I tried implementing a media player for each sound file and button but the app crashes on start up.
I have 10 buttons with 10 corresponding sound files that are located in the raw file in src/res/raw/
Any idea on how to make it work?
//this is a breaking bad soundboard app, so please excuse the language. Sorry if you find it offensive
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
whatup = (Button)this.findViewById(R.id.button);
haveatit = (Button)this.findViewById(R.id.button2);
hello = (Button)this.findViewById(R.id.button3);
whining = (Button)this.findViewById(R.id.button7);
money = (Button)this.findViewById(R.id.button4);
yeah= (Button)this.findViewById(R.id.button8);
miserable = (Button)this.findViewById(R.id.button5);
mother = (Button)this.findViewById(R.id.button9);
gatorade = (Button)this.findViewById(R.id.button6);
science = (Button)this.findViewById(R.id.button10);
whatup.setOnClickListener(this);
haveatit.setOnClickListener(this);
hello.setOnClickListener(this);
whining.setOnClickListener(this);
money.setOnClickListener(this);
yeah.setOnClickListener(this);
miserable.setOnClickListener(this);
mother.setOnClickListener(this);
gatorade.setOnClickListener(this);
science.setOnClickListener(this);
WhatUp = MediaPlayer.create(MainActivity.this, R.raw.whatupb);
HaveAtIt = MediaPlayer.create(MainActivity.this, R.raw.haveatit);
Hello = MediaPlayer.create(MainActivity.this, R.raw.hello);
Whining = MediaPlayer.create(MainActivity.this, R.raw.stopwhining);
Money = MediaPlayer.create(MainActivity.this, R.raw.wheresmymoney);
Yeah = MediaPlayer.create(MainActivity.this, R.raw.yeahb);
Miserable = MediaPlayer.create(MainActivity.this, R.raw.miserableb);
Mother = MediaPlayer.create(MainActivity.this, R.raw.motherofgod);
Gatorade = MediaPlayer.create(MainActivity.this, R.raw.gatorade);
Science = MediaPlayer.create(MainActivity.this, R.raw.yeahscience);
}
this is for handling when the button is pressed. Obviously there needs to be more, but I was just testing 1 button and it crashes when I try starting it.
#Override
public void onClick(View view) {
if(view==whatup)
{
WhatUp.start();
}
}
Log Cat Errors:
http://imgur.com/ZWYsLl7
I assume your sounds might be sound_1, sound_2, sound_3, etc. and your buttons are button_1, button_2 and so on..
You should create a loop to get the ids in onCreate method:
for (int i = 0; i < 10; i++) {
// get the id for buttons
int btnId = getResources().getIdentifier("button_"+i, "id", getPackageName());
// get the res for sounds
int rawId = getResources().getIdentifier("sound_"+i, "raw", getPackageName());
// set a click listener to all your buttons
button[i] = (Button) findViewById(id);
button[i].setOnClickListener(new OnClickListener() {
public void onClick(View view) {
// create the media player with the raw id
mp = MediaPlayer.create(MainActivity.this, rawId);
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
// avoid NullPointerException see the links below
mp.release();
}
});
// play the sound
mp.start();
}
});
}
Read the topic reference: Using MediaPlayer. You could also get identifer with the context: How to dynamically generate the raw resource identifier in android? and this might help you for explanation of release() method: Play sound on button click - Null pointer exception and read the Releasing the MediaPlayer part from Using MediaPlayer. I'm not sure but it should do the trick..
Good luck.
UPDATE
Change this check if(view==whatup) to if(view.getId() == R.id.button).
In onClick method you need to check the id regarding the view, with getId() method.
Related
I simply want to play a mp3 file when I click a button in android studio.
My problem is that with the 2 methods I use the sound is played but for some reason, I hear it like an extremely distorted super slow motion sound. While if I normally open the file it is ok.
!!!!!METHOD 1:
I declared:
SoundPool mySound;
int soungId;
I initialize:
mySound = new SoundPool(1, AudioManager.STREAM_MUSIC,0);
soungId = mySound.load(this, R.raw.asd,1);
Then is use an action listener:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mySound.play(soungId,1,1,1,0,1);
}
});
!!!!!METHOD 2:
I declare:
MediaPlayer mp = null;
I use listener:
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
managerOfSound();
}
});
My managerOfSound mathod :
public void managerOfSound() {
if (mp != null) {
mp.reset();
mp.release();
}
mp = MediaPlayer.create(this, R.raw.www);
mp.reset();
mp.start();
}
It may be because the Soundpool instance of the MaxStreams maximum number (maximum number of concurrent streams) is too low
SoundPool mySound;
mySound = new SoundPool(10, AudioManager.STREAM_MUSIC,0);
try this,
MediaPlayer mp = new MediaPlayer();
// Set data source -
setDataSource("/sdcard/path_to_song");
// Play audio
mp.start();
// Pause audio
mp.pause();
// Reset mediaplayer
mp.reset();
// Get song length duration - in milliseconds
mp.getDuration();
// Get current duration - in milliseconds
mp.getCurrentDuration();
// Move song to particular second - used for Forward or Backward
mp.seekTo(positon); // position in milliseconds
// Check if song is playing or not
mp.isPlaying(); // returns true or false
http://www.androidhive.info/2012/03/android-building-audio-player-tutorial/
I'm working on an app in which there is a grid layout with 8 buttons and each attached to a sound. Now I'm able to play the audio on the click of a button but when I press the same button again the audio doesn't stop.
All my buttons are attached to a common onClick method and the class file retrieves the id of the button and matches with the sound file present in the raw folder.
I'm using a flag for this but don't know where I'm going wrong.
My Code
boolean play = true;
MediaPlayer mediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void buttonTapped(View view)
{
int id = view.getId();
String ourID = "";
ourID = view.getResources().getResourceEntryName(id);
int resourceID = getResources().getIdentifier(ourID, "raw", "com.starprojects.gridlayoutdemo");
mediaPlayer = MediaPlayer.create(this,resourceID);
if(play)
{
mediaPlayer.start();
play = false;
}
else {
// mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
// play = true;
}
// mediaPlayer = null;
Log.i("button tapped",ourID);
}
}
define mediaPlayer outsite of function, then do that
public void buttonTapped(View view) {
int id = view.getId();
String ourID = "";
ourID = view.getResources().getResourceEntryName(id);
int resourceID = getResources().getIdentifier(ourID, "raw", "com.starprojects.gridlayoutdemo");
stopPlayer();
mediaPlayer = MediaPlayer.create(this,resourceID);
if (mediaPlayer != null)
mediaPlayer .start();
}
public void stopPlayer() {
if (mediaPlayer != null) {
mediaPlayer .stop();
mediaPlayer .release();
}
mediaPlayer = null;
}
thats all :)
This may or may not be related to your problem, but don't forget to call
mediaPlayer.release();
mediaPlayer = null;
when you are finished. If you do not, resources get built up and start affecting sound outside of the app. Keep in mind a new MediaPlayer is being allocated every time you press the button. I have done this in a previous app and the sound stopped working after a few minutes.
Let me know if this changes anything.
As a matter of fact, you can try making your MediaPlayer a member of the class (defined outside the function) since you only need one sound playing at once. If it isn't null or .isPlaying(), release it. Otherwise, create and play.
I need to have the same short wav file (1 second) play each time the user presses a single button. I have the following code that works for about 30 clicks and then the app "Force closes" on the device. I think what is going on is that new instances of media player are being created and then the instances build up (approx 30 clicks) and the app crashes. So I then added the "release" instance in the hope that on button-click the wav would play and then the mediaplayer would be released. However, it doesnt work that way. With the mp.release() no sound is played possibly becaue the medaiplayer gets released too soon for the user to hear the sound?
Anyone have a good tip to help me getting this to work? Thank you all so much.
Button button2 = (Button) findViewById(R.id.button10);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
mp.start();
mp.release();
Its simple just create the MediaPlayer once, and play it over time.
private MediaPlayer mp;
public void onClick(View v) {
// Perform action on click
if (mp == null){
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
}
mp.start();
}
Why use MediaPlayer, when SoundPool is better suited for small audio files? As a base you could use this:
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 70);
final HashMap<Integer, Integer> soundPoolMap = new HashMap<Integer, Integer>();
final int soundID = 4;
soundPoolMap.put(soundID, soundPool.load(this, R.raw.wav_sound, 4));
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener()
{
public void onLoadComplete(SoundPool soundPool, int sampleId, int status)
{
if (sampleId == 4)
{
soundPool.play(4, 50, 50, 1, 0, 1f);
}
}
});
Here is the simple solution that will work
MediaPlayer mp;
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
public void onClick(View v) {
// Perform action on click
if(mp.isPlaying())
{
mp.stop();
mp.reset();
mp.release();
}
mp = MediaPlayer.create(getApplicationContext(), R.raw.clicker);
mp.start();
This is will check if mediaplayer is already playing..If it already playing it will stop and release it and then initialize that mediaplayer(mp) object and start the mediaplayer.
If it is not playing it will execute the code after the if statement and the start the media player after initialzing the mediaplayer object(mp in this case)
To learn more about MediaPlayer study this http://developer.android.com/reference/android/media/MediaPlayer.html. Study the Mediaplayer life cycle
i have a button that plays a sound.
When i push the button multiple times, it plays the sound multiple times.
This is oke, i want this.
But when i click the stop button it must stop all sounds currently playing.
I used:
while (mediaPlayer.isPlaying()){mediaPlayer.stop();}
but it is not working, the sounds keep on playing. Can someone help me?
Here is my full code:
public class HelloSoundboard extends Activity {
MediaPlayer mediaPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.atyourservice);
mediaPlayer.start();
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
while (mediaPlayer.isPlaying()){mediaPlayer.stop();}
// mediaPlayer.stop();
}
});
}
}
SoundPool is a much better alternative for this purpose. I would caution strongly against instantiating multiple MediaPlayer instances as most systems do not have the resources to generate many parallel active instances. You wil find on many device that hitting the button upwards of 5 times will cause a memory based crash.
As far as stopping all active streams, there is not baked-in function for this, but it's easy to accomplish in a manner to similar to your existing code. As a side note, there is an autoPause() method, which halts all streams, but it doesn't truly end their playback (as the method name insinuates). Here is a simple example to manage your audio streams:
//SoundPool initialization somewhere
SoundPool pool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
//Load your sound effect into the pool
int soundId = pool.load(...); //There are several versions of this, pick which fits your sound
List<Integer> streams = new ArrayList<Integer>();
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int streamId = pool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
streams.add(streamId);
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for (Integer stream : streams) {
pool.stop(stream);
}
streams.clear();
}
});
It is much more memory efficient to manage a list of streamID values than MediaPlayer instances, and your users will thank you. Also, note that it is safe to call SoundPool.stop() even if the streamID is no longer valid, so you don't need to check for existing playback.
HTH
I'm not sure about this, but I think is better if you use a SoundPool.
"SoundPool is designed for short clips which can be kept in memory decompressed for quick access, this is best suited for sound effects in apps or games".
"MediaPlayer is designed for longer sound files or streams, this is best suited for music files or larger files".
You can use a list of MediaPlayers:
List<MediaPlayer> mps = new ArrayList<MediaPlayer>();
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.atyourservice);
mp.start();
mps.add(mp);
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for (int i = mps.size() - 1; i >= 0; --i) { //changed ++i to --i
if (mps.get(i).isPlaying()) {
mps.get(i).stop();
}
mps.remove(i);
}
}
});
How do I set up an audiofile to play when a user touches an image.
Where should I store the audio file and what code should I use to actually play the file?
I don't want to bring up the MediaPlayer interface or anything like that.
I was thinking of doing it like this:
foo = (ImageView)this.findViewById(R.id.foo);
foo.setOnClickListener(this);
public void onClick(View v) {
if (foo.isTouched()) {
playAudioFile();
}
}
Thanks
This won't create a bring up the MediaPlayer interface... it will just play the sound you want.
Button boton = (Button) findViewById(R.id.boton);
boton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaPlayer mp = MediaPlayer.create(TestSonido.this, R.raw.slayer);
mp.start();
}
});
In this case, R.raw.slayer represents an audio file called slayer.mp3 that is stored in the res/raw/ folder and once you click the button the droid will rock you...
You can also achieve the same using SoundPool.
MediaPlayer first loads the whole sound data in memory then play, so it produces some lag when we switch among sounds frequently.
SoundPool is a better option with small size sound file and produces better result with .ogg media file.
SoundPool pl = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
// 5 indicates the maximum number of simultaneous streams for this SoundPool object
pl.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// The onLoadComplet method is called when a sound has completed loading.
soundPool.play(sampleId, 1f, 1f, 0, 0, 1);
// second and third parameters indicates left and right value (range = 0.0 to 1.0)
}
});
Button btn = findViewById(R.id.boton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int sound = pl.load(this, R.raw.sound_01, 0);
}
});
public void aud_play(View view) {
if (!mp.isPlaying()) { //If media player is not playing it.
mp = MediaPlayer.create(this, R.raw.audio_name);
mp.start();
} else {// Toast of Already playing ...
}
}