0

I have asked this question 2 times now still haven't got it to work. Any help would be awesome

My ProgressBar does not reset after audio is done, the bar just stays to the max blue line. I ask a question before on this and got it working but now just stopped working and not sure why it doesn't. Any help would be awesome.

All I want is it to chose a audio at random then play one and when finished you can press play again to listen to the same audio it chose at random.

Heres code:

 public class player2 extends Activity implements Runnable {


private  MediaPlayer mp;
private ProgressBar progressBar;
private ImageButton pauseicon;
private final int NUM_SOUND_FILES = 3;  //*****REPLACE THIS WITH THE ACTUAL NUMBER OF SOUND FILES YOU HAVE*****
private int mfile[] = new int[NUM_SOUND_FILES];
private Random rnd = new Random();


   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.player_2);
        pauseicon = (ImageButton) findViewById(R.id.pauseicon);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        getActionBar().setDisplayHomeAsUpEnabled(true);



        mfile[0] = R.raw.sound04;  //****REPLACE THESE WITH THE PROPER NAMES OF YOUR SOUND FILES
        mfile[1] = R.raw.sound05;  //PLACE THE SOUND FILES IN THE /res/raw/ FOLDER IN YOUR PROJECT*****
        mfile[2] = R.raw.sound06;
        // Listeners
        /**
         * Play button click event
         * plays a song and changes button to pause image
         * pauses a song and changes button to play image
         * */


        try{
             mp = MediaPlayer.create(player2.this, mfile[rnd.nextInt(NUM_SOUND_FILES)]);
             mp.seekTo(0);
             mp.start(); ;         
             progressBar.setVisibility(ProgressBar.VISIBLE);
             progressBar.setProgress(0);
             progressBar.setMax(100);

             new Thread(this).start();

         } catch (IllegalArgumentException e) {
             e.printStackTrace();
         } catch (IllegalStateException e) {
             e.printStackTrace();
         }

        mp.setOnCompletionListener(new OnCompletionListener() {

            public void onCompletion(MediaPlayer mp) {
                pauseicon.setImageResource(R.drawable.playicon);
            }
        });

        pauseicon.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                 // No need to check if it is pauseicon

        if(mp.isPlaying()){
            mp.pause();
         ((ImageButton) v).setImageResource(R.drawable.playicon);

        } else {
            mp.start();
            ((ImageButton) v).setImageResource(R.drawable.pauseicon);
     }}});

   }

   public void run() {
        int currentPosition= 0;
        int total = mp.getDuration();
        while (mp!=null && currentPosition<=total) {
            try {
                Thread.sleep(1000);
                currentPosition= mp.getCurrentPosition();
            } catch (InterruptedException e) {
                return;
            } catch (Exception e) {
                return;
            }            
            progressBar.setProgress(currentPosition);
        }
    }

   @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);


        if (mp != null)
        if(mp.isPlaying())
              mp.stop();

          mp.release();

            return true;
        default:
            return super.onOptionsItemSelected(item);

    }

        }
    @Override 
    public void onBackPressed(){
      if (mp != null){
          if(mp.isPlaying())
              mp.stop();

          mp.release();
      }

      //there is no reason to call super.finish(); here
      //call super.onBackPressed(); and it will finish that activity for you
      super.onBackPressed(); 
    }
    }
user2407147
  • 1,508
  • 2
  • 22
  • 40

1 Answers1

1

I did not check all the code thoroughly, but at a quick glance I would guess that your thread (which updates the progress bar) is stopping at completion and you never start it again (ie. when the user clicks play again). Just try restarting the thread in your pauseicon.setOnClickListener (when playback is complete). Example:

pauseicon.setOnClickListener(new View.OnClickListener() {

   public void onClick(View v) {
      if(mp.isPlaying()) {
         mp.pause();
         ((ImageButton) v).setImageResource(R.drawable.playicon);
      } else {
         mp.start();
         ((ImageButton) v).setImageResource(R.drawable.pauseicon);
         // RESTART THE UPDATE THREAD //
         new Thread(this).start();
      }
   }
});

EDIT using a static variable to store thread so that it can be restarted from the view's onClick method:

// add this to your class as a member
static Thread progressThread = new Thread(this);

// add this to BOTH onCreate and onClick
progressThread.start();

If this does not work (I can't test it out right now), you can simply keep the thread running, for example:

// flag to set when thread should be actively running
static boolean runThread = true;

// change your run method to something as follows
public void run() {
    while ( runThread )  {
       if ( mp != null && currentPosition <= total )  {
          int currentPosition= 0;
          int total = mp.getDuration();
          try {
             Thread.sleep(1000);
             currentPosition= mp.getCurrentPosition();
          } catch (InterruptedException e) {
             return;
          } catch (Exception e) {
             return;
          }            
          progressBar.setProgress(currentPosition);
       }
       else
          Thread.sleep(1000);
    }
}

// then when you no longer need to update the progress bar set the flag to false,
// which will cause your thread to finish. this can go anywhere, depending on
// your needs
runThread = false; 
free3dom
  • 18,729
  • 7
  • 52
  • 51
  • I get this error The constructor Thread(new View.OnClickListener(){}) is undefined. But thanks for trying, any suggestions :) – user2407147 Sep 01 '13 at 18:21
  • Of course, that wouldn't work...my bad ;) The `onClick` is actually in the `View` class, not your Activity. It should work if you use `new Thread(player2).start();`. Sorry for the confusion. – free3dom Sep 01 '13 at 22:06
  • Now get this error player2 cannot be resolved to a variable. :S – user2407147 Sep 01 '13 at 22:24
  • Okay, might be a good idea to save the newly created thread to a static variable during creation, then you can start it again in `onClick` (without recreating it). I'll add some example code to the answer to illustrate. – free3dom Sep 01 '13 at 23:22
  • Ok thanks a lot! I'll test it tomorrow morning and see what happens. – user2407147 Sep 02 '13 at 00:30
  • The first way I get the error saying Thread already started. The second way I get these errors Multiple markers at this line - total cannot be resolved to a variable - currentPosition cannot be resolved to a variable Also Syntax error on token "runThread", VariableDeclaratorId expected after this token – user2407147 Sep 02 '13 at 11:41
  • Don't copy/paste my code...it is just an example (which I did not try to compile). Look at the code and do the implementation yourself. Ask if you don't understand the concept, or where the parts of the code should go. – free3dom Sep 02 '13 at 12:58
  • For the first one would the "static Thread progressThread" go under the private Random rnd = new Random(); and the progressThread.start(); go under setContentView(R.layout.player_2); and under public void onClick(View v) { – user2407147 Sep 02 '13 at 17:40
  • That sounds right, except that the second `start()` call should go in the `else` block of the `onClick` (the same place as the `mp.start();` call). If you get an `already started` error for the second call, you could do a check on the [thread state](http://developer.android.com/reference/java/lang/Thread.html#getState%28%29) and only start it if it is `RUNNABLE`. – free3dom Sep 02 '13 at 19:57
  • I don't think you can use (this) in a static so I just put new Thread(); I changed the new Thread(this).start(); under the try of the MediaPlayer to progressThread.start(); but then nothing moves which probably means It can't find the thread due to taking out the (this). Any suggestions of what I can do? – user2407147 Sep 02 '13 at 21:21
  • And I added on the setOnCompletionListener progressThread.stop(); Would this work if I get the it to find the Thread. I don't know if it would work but seem like it would in my head. – user2407147 Sep 02 '13 at 21:25
  • Stopping the thread that way is never recommended - see the [documentation](http://developer.android.com/reference/java/lang/Thread.html#stop%28java.lang.Throwable%29). The thread should stop automatically once the `currentPosition <= total` is satisfied (i.e. the while loop will end and the run will come to an end). And since you are not recreating the thread in `onClick` (you are reusing the thread you created in `onCreate`) you will **not** need to specify the runnable (i.e. `this`) again. Just make sure that you start the media player **before** restarting the thread. – free3dom Sep 02 '13 at 22:59
  • Why when I use progressThread.start(); instead of new Thread(this).start; surly it should do the same thing? I have the "static Thread progressThread = new Thread();" in place so why should it not? – user2407147 Sep 03 '13 at 00:03
  • Don't worry. Re Tried your second way. IT WORKED Thanks! Had to changed a couple of things but WORKED. Thanks so much dude for all help :) – user2407147 Sep 03 '13 at 00:21
  • No problem, glad you go it sorted out :) – free3dom Sep 03 '13 at 07:35