简体   繁体   中英

How do i fix java.lang.NullPointerException in playing mp3files from a raw folder in AndroidStudio?

I wanted to created a playlist such that when the user clicks on the song, it plays and when he clicks on the next song, the song that is playing will stop and resume the next song. Additionally, i have placed a stop button which also stops the song which is being played. Now, here is the problem when i write the following block of code, my program crashes and my error log shows java.lang.NullPointerException-

 public void playSong(int res)
    {
        if(mp.isPlaying()) {
            mp.reset();
            mp = MediaPlayer.create(getApplicationContext(), resid[res]);
            mp.start();
        }

        else {
            mp = MediaPlayer.create(getApplicationContext(), resid[res]);
            mp.start();
        }


    }

But if i change the code to the following, it works fine. I see that mp.reset() is the issue. But I dont know how to fix it because without it the when i click on a song and there is already a song which is playing, both the songs play at the same time.-

   public void playSong(int res)
    {
            mp = MediaPlayer.create(getApplicationContext(), resid[res]);
            mp.start();
     }

//Following is my full code. Please help me to fix the bug. Thanks--

package com.example.user.musicp;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

public class MainActivity extends Activity {

    Button b;
    private MediaPlayer mp;
    private ListView v;
    private int [] resid = {R.raw.k,R.raw.u};
    private String [] name = {"k","u"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        v = (ListView) findViewById(R.id.listView);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, name);

        v.setAdapter(adapter);
        b = (Button) findViewById(R.id.StopButton);

        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              //  mp.stop();
              //  mp.release();
                onDestroy();

            }
        });

        v.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                playSong(i);
              //  mp = MediaPlayer.create(MainActivity.this, resid[i]);
              //  mp.start();
            }
        });

    }

        public void playSong(int res)
    {
        if(mp.isPlaying()) {
            mp.reset(); //this is where the issue begins
            mp = MediaPlayer.create(getApplicationContext(), resid[res]);
            mp.start();
        }

        else {
            mp = MediaPlayer.create(getApplicationContext(), resid[res]);
            mp.start();
        }


    }

    @Override

    public void onDestroy() {

        super.onDestroy();
        mp.release();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

在此处输入图片说明

References:- http://www.geeks.gallery/how-to-play-mp3-file-from-raw-folder-in-a-listview-android/

After some valuable suggestion by some users, i edited my code and was able to fix the bug. But here is the thing when i click on a song and there is a previous song which is already playing, i want the previous song to stop and the new song to be played but unfortunately both the songs keep playing. I tried every possible means to fix it but i may be doing mistake somewhere. Here is my edited code and when i implement the following, then my program crashes. PLease help me out -

 public void playSong(int res)
    {



        boolean isplaying = mp.isPlaying();

         if(isplaying)
         {
             mp.stop();
             mp = MediaPlayer.create(getApplicationContext(), resid[res]);
             mp.start();
         }

         else
         {
             mp = MediaPlayer.create(getApplicationContext(), resid[res]);
             mp.start();
         }

}

Here is the complete working code just in case someone gets stuck in the future. Thanks a lot to StackOverflow users for helping me out. Cheers!

package com.example.user.musicp;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

import java.io.IOException;

public class MainActivity extends Activity {

    Button b,c;
    private MediaPlayer mp;
    private ListView v;
    private int [] resid = {R.raw.k,R.raw.u};
    private String [] name = {"k","u"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mp = new MediaPlayer();

        v = (ListView) findViewById(R.id.listView);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, name);

        v.setAdapter(adapter);
        b = (Button) findViewById(R.id.StopButton);
        c = (Button) findViewById(R.id.next);


        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mp.stop();


            }
        });

        c.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent in = new Intent("com.example.user.musicp.SPLASH");
                startActivity(in);
            }
        });
        v.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                playSong(i);
              //  mp = MediaPlayer.create(MainActivity.this, resid[i]);
              //  mp.start();
            }
        });

    }

        public void playSong(int res)
    {
        mp.reset();// stops any current playing song

        mp = MediaPlayer.create(getApplicationContext(), resid[res]);// create's
        mp.start(); // starting mediaplayer






    }

    @Override

    public void onDestroy() {

        super.onDestroy();
        mp.release();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
if(mp.isPlaying()) { // mp only declared (still null)
    mp.reset();
    mp = MediaPlayer.create(getApplicationContext(), resid[res]);
    mp.start();     }

else {
    mp = MediaPlayer.create(getApplicationContext(), resid[res]);
    mp.start();
}

I suppose that at the moment of the if statement mp is only declared. That's why you can not do mp.isPlaying() because mp is still null .

That should explain why in this case it works fine

public void playSong(int res)
{
    // here mp is still null
    mp = MediaPlayer.create(getApplicationContext(), resid[res]); // From here on we can use mp
    mp.start();
 }

Here mp is not used before initialization, hence no null pointer exception.

EDIT : Creating the mediaplayer in the playSong method is a bit weird. This means every time playSong is called mp gets reassigned. A better place could be in the class' constructor. Doing so you can be sure mp will not be null when playSong gets invoked.

EDIT 2 : You're still reassigning mp in playSong . I would suggest to do this :

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mp = MediaPlayer.create(getApplicationContext(), resid[res]);
    // ...
}

And I would implement playSong like this :

public void playSong(int songIndex)
{
    if(mp.isPlaying()) {
        mp.pause(); // Pause the current track
    }

    mp.selectTrack(songIndex); // Select the requested track
    mp.start();
}

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