1

I wrote this code in order to make a soundboard like app

public class ButtonSoundActivity extends Activity implements OnClickListener {
    private Button buttons[];
    private MediaPlayer mediaPlayers[];

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);     
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseSounds();
    }

    @Override
    protected void onResume() {
        super.onResume();
        initContent();
    }

    @Override
    protected void onStop() {
        super.onStop();
        releaseSounds();
    }

    /**
     * Initialise all the content :
     * buttons, media players and set click listeners for the buttons
     */
    private void initContent() {
        buttons = new Button[5];
        mediaPlayers = new MediaPlayer[5];

        buttons[0] = (Button)findViewById(R.id.button0);
        buttons[1] = (Button)findViewById(R.id.button1);
        buttons[2] = (Button)findViewById(R.id.button2);
        buttons[3] = (Button)findViewById(R.id.button3);
        buttons[4] = (Button)findViewById(R.id.button4);

        mediaPlayers[0] = MediaPlayer.create(ButtonSoundActivity.this, R.raw.sound1);
        mediaPlayers[1] = MediaPlayer.create(ButtonSoundActivity.this, R.raw.sound2);
        mediaPlayers[2] = MediaPlayer.create(ButtonSoundActivity.this, R.raw.sound3);
        mediaPlayers[3] = MediaPlayer.create(ButtonSoundActivity.this, R.raw.sound4);
        mediaPlayers[4] = MediaPlayer.create(ButtonSoundActivity.this, R.raw.sound5);


        for(int i=0; i<5; i++) {
            buttons[i].setOnClickListener(this);
        }      
    }

    public void onClick(View v) {
        stopSounds();
        for(int i=0; i<5; i++)
            if(v.getId() == buttons[i].getId()) {
                if(mediaPlayers[i] != null)
                mediaPlayers[i].start();
            }
    }

    /**
     * Stop the previous sound when another button is clicked
     * so that the sounds don't overlap
     */
    private void stopSounds() {
        for(int i=0; i<5 ;i++)
            if(mediaPlayers[i] != null)
            if(mediaPlayers[i].isPlaying()) {
                mediaPlayers[i].pause();
                mediaPlayers[i].seekTo(0);
            }
    }

    /**
     * Release all sounds and empty the mediaPlayers array
     */
    private void releaseSounds() {
        for(int i=0; i<5;i++) {
            if(mediaPlayers[i] != null) {
                mediaPlayers[i].stop();
                mediaPlayers[i].release();
                mediaPlayers[i] = null;                 
            }
        }
    }       
}

the xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="button0" android:id="@+id/button0"/>

    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="button1" android:id="@+id/button1"/>

    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="button2" android:id="@+id/button2"/>      

    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="button3" android:id="@+id/button3"/>

    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="button4" android:id="@+id/button4"/>      
</LinearLayout>

The problem is that if I click a button multiple times in a row, the sound doesn't play anymore, or sometime, when I first open the app, it crashes when I click a button. The error says it's related to the stopSounds method

error code

So, does anyone have an answer?

Edit: I added the if() before each mediaPlayer element to check if they are null, also I followed this method:

            AssetFileDescriptor fileDescriptor = getResources().openRawResourceFd(R.raw.sound1);
        mediaPlayers[0] = new MediaPlayer();

        try {
            mediaPlayers[0].setDataSource(fileDescriptor.getFileDescriptor());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            mediaPlayers[0].prepare();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

but without any luck :(

Edit 2: I got it working :) , I just had to make sure that the mediaPlayer array is empty when I restart the app. Also I added the onPause() and onResume() functions.

Ovidiu Birgu
  • 439
  • 2
  • 6
  • 24

1 Answers1

3

You are getting a NullPointerException at line 57, inside your stopSounds method. Could you post this line all by itself?

Most likely one of the objects in mediaPlayers is null. Try stepping through the debugger and see what the array looks like when you first enter the stopSounds method.

skynet
  • 9,898
  • 5
  • 43
  • 52
  • 2
    ' if(mediaPlayers[i].isPlaying()) { ' this is the line – Ovidiu Birgu Nov 10 '11 at 14:15
  • 2
    I even checked if it is null ' if(!mediaPlayers[i].equals(null)) if(mediaPlayers[i].isPlaying()) { mediaPlayers[i].pause(); mediaPlayers[i].seekTo(0); } ' – Ovidiu Birgu Nov 10 '11 at 14:18
  • 1
    As the docs state, [`MediaPlayer.create()` can return null if creation failed](http://developer.android.com/reference/android/media/MediaPlayer.html#create%28android.content.Context,%20int%29). Try putting null checks before you try to call methods on the MediaPlayer objects in the array – skynet Nov 10 '11 at 14:18
  • 2
    That method of checking whether it is null will still throw a NullPointerException if it is null. Use `if (!mediaPlayers[i] == null)` instead – skynet Nov 10 '11 at 14:20
  • 2
    you are right, thanks! but now, some buttons do not work(the sound does not play anymore), some of them work – Ovidiu Birgu Nov 10 '11 at 14:24
  • That is due to the MediaPlayer associated with that button being null. Check logcat as it might tell you why creation failed – skynet Nov 10 '11 at 14:30
  • yes, some mediaplayer elements are not created : http://pastebin.com/j46ax0QS also, line 35 is this: mediaPlayers[2] = MediaPlayer.create(this, R.raw.sound3); Could the problem be related to the sounds? Bad encoding? – Ovidiu Birgu Nov 10 '11 at 14:35
  • That looks like a general error opening the raw resource. I would suggest making sure it can be opened elsewhere, and is not corrupted. Perhaps this question could help http://stackoverflow.com/questions/3761305/android-mediaplayer-throwing-prepare-failed-status-0x1-on-2-1-works-on-2-2 – skynet Nov 10 '11 at 14:38