0

Hi I am new to android and I am learning by example. I am trying to make an activity that has a list view of all songs in my raw folder with media player controls at the bottom. I have everything working so far but I can't seem to get the SeekBar to stop force closing.

Here is the code:

public class music extends ListActivity implements Runnable {

    private ArrayList<sound> mSounds = null;

    private soundadapter mAdapter = null;
    private ImageButton playbtn;
    private SeekBar seekbar;
    private int total;
    private MediaPlayer mp = null;
    private TextView selelctedFile = null;

    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.music);


        selelctedFile = (TextView) findViewById(R.id.selectedfile);

        seekbar = (SeekBar) findViewById(R.id.seekbar);
        seekbar.setProgress(0);

        // create a simple list

        mSounds = new ArrayList<sound>();

        sound s = new sound();

        s.setDescription("Rudolph The Red Nosed Reindeer");

        s.setSoundResourceId(R.raw.rudolphtherednosereindeer);

        mSounds.add(s);

        s = new sound();

        s.setDescription("Battery");

        s.setSoundResourceId(R.raw.battery);

        mSounds.add(s);

        mAdapter = new soundadapter(this, R.layout.listitem, mSounds);

        setListAdapter(mAdapter);

        playbtn = (ImageButton) findViewById(R.id.play);
        playbtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // TODO Auto-generated method stub
                try {
                    if (mp.isPlaying()) {
                        mp.pause();
                        playbtn.setImageResource(android.R.drawable.ic_media_play);

                    } else {
                        mp.start();
                        playbtn.setImageResource(android.R.drawable.ic_media_pause);

                    }
                } catch (Exception e) {

                    e.printStackTrace();
                    // TODO: handle exception
                }

            }
        });

    }

    @Override
    public void onListItemClick(ListView parent, View v, int position, long id) {

        sound s = (sound) mSounds.get(position);
        if (mp != null) {
            mp.reset();
            mp.release();

        }

        mp = MediaPlayer.create(this, s.getSoundResourceId());
        selelctedFile.setText(s.getDescription());
        playbtn.setImageResource(android.R.drawable.ic_media_pause);
        mp.start();
        total = mp.getDuration();
        seekbar.setMax(total);

        seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

            @Override
            public void onStopTrackingTouch(SeekBar seekbar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekbar) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
                // TODO Auto-generated method stub
                if (fromUser) {
                    mp.seekTo(progress);
                    seekBar.setProgress(progress);
                }
            }
        });

        Thread currentThread = new Thread(this);
        currentThread.start();

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

        try {
            while (mp != null) {
                int currentPosition = mp.getCurrentPosition();
                Message msg = new Message();
                msg.what = currentPosition;
                threadHandler.sendMessage(msg);
                Thread.sleep(100);
            }
        }

        catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

        }
    }

    private Handler threadHandler = new Handler() {
        public void handleMessage(Message msg) {
            // super.handleMessage(msg);
            // txt.setText(Integer.toString(msg.what));
            seekbar.setProgress(msg.what);
        }
    };

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub

        mp.stop();
        mp.release();
        mp = null;
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        if(mp != null) {
            mp.stop();
            mp.release();
            mp = null;
        }
    }   
}

and here is the error i keep getting when i click several times on different songs:

04-14 02:53:00.452: W/dalvikvm(27452): threadid=19: thread exiting with uncaught    exception (group=0x40018560)    
04-14 02:53:00.466: E/AndroidRuntime(27452): FATAL EXCEPTION: Thread-22
04-14 02:53:00.466: E/AndroidRuntime(27452): java.lang.IllegalStateException
04-14 02:53:00.466: E/AndroidRuntime(27452): at android.media.MediaPlayer.getCurrentPosition(Native Method)
04-14 02:53:00.466: E/AndroidRuntime(27452): at net.cybercore.collapsingfromwithin.music.run(music.java:145)
04-14 02:53:00.466: E/AndroidRuntime(27452): at java.lang.Thread.run(Thread.java:1019)

Line error 145 is :
int currentPosition = mp.getCurrentPosition();

I cannot for the life of me figure out why it works for 3 or 4 times playing and then it kills the app.

Any help is appreciated. I have already looked at several other sites for examples including http://www.androidhive.info/2012/03/android-building-audio-player-tutorial/ and http://www.androiddevblog.net/android/playing-audio-in-android

**

UPDATE

** I think I fixed it. thanks for your help I found Thread using for seekbar on android mediaplayer so i changed it to

@Override
public void run() {
    // TODO Auto-generated method stub

    try {
        while (mp != null) {
            int currentPosition = mp.getCurrentPosition();
            Message msg = new Message();
            msg.what = currentPosition;
            threadHandler.sendMessage(msg);

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("interrupt exeption" + e);
            }
        }
    }

    catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        System.out.println("My exeption" + e);
    } 
}

I still get the errors but they are not killing my app. I don't think this is right way to do it but its working.

Shivam Kumar
  • 1,892
  • 2
  • 21
  • 33
Pestilence
  • 11
  • 1
  • 7

1 Answers1

0

You should prepare your media player when instanciating it.

A MediaPlayer object must first enter the Prepared state before playback can be started. There are two ways (synchronous vs. asynchronous) that the Prepared state can be reached: either a call to prepare() (synchronous) which transfers the object to the Prepared state once the method call returns, or a call to prepareAsync() (asynchronous) which first transfers the object to the Preparing state after the call returns (which occurs almost right way) while the internal player engine continues working on the rest of preparation work until the preparation work completes. When the preparation completes or when prepare() call returns, the internal player engine then calls a user supplied callback method, onPrepared() of the OnPreparedListener interface, if an OnPreparedListener is registered beforehand via setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener).

Read it here

so you should call mp.prepare() after instanciating the player.

also you should make sure the media player in playing to run the run method. I'd start by adding mp.isPlaying() to the while line.

while (mp != null && mp.isPlaying()) {
           ...

        }

IllegalStateException means that you are on an illegal state to call that method, like for instance, if the player is stopped.

I'm not sure, but I think this will stop the run method when you pause the music. So you should try to avoid this. I create a boolean to identify that the player is playing or paused and use it on the while.

Nuno Gonçalves
  • 6,202
  • 7
  • 46
  • 66
  • thanks for your reply...I am now getting an error on that line. – Pestilence Apr 14 '12 at 07:52
  • 04-14 03:50:59.505: W/System.err(30752): at android.media.MediaPlayer.isPlaying(Native Method) 04-14 03:50:59.505: W/System.err(30752): at net.cybercore.collapsingfromwithin.music.run(music.java:142) 04-14 03:50:59.505: W/System.err(30752): at java.lang.Thread.run(Thread.java:1019) – Pestilence Apr 14 '12 at 07:53
  • Is it the same exception being thrown? – Nuno Gonçalves Apr 14 '12 at 07:55
  • 04-14 02:53:00.452: W/dalvikvm(27452): threadid=19: thread exiting with uncaught exception (group=0x40018560) 04-14 02:53:00.466: E/AndroidRuntime(27452): FATAL EXCEPTION: Thread-22 04-14 02:53:00.466: E/AndroidRuntime(27452): java.lang.IllegalStateException 04-14 02:53:00.466: E/AndroidRuntime(27452): at android.media.MediaPlayer.getCurrentPosition(Native Method) 04-14 02:53:00.466: E/AndroidRuntime(27452): at net.cybercore.collapsingfromwithin.music.run(music.java:145) 04-14 02:53:00.466: E/AndroidRuntime(27452): at java.lang.Thread.run(Thread.java:1019) – Pestilence Apr 14 '12 at 08:00
  • MediaPlayer.create already prepares the file for you i just keep getting the error on int currentPosition = mp.getCurrentPosition(); – Pestilence Apr 14 '12 at 08:20
  • I updated my question with what is working thanks agian for your quick reposnse – Pestilence Apr 14 '12 at 08:33