TextView not drawing from within button onClick - android

I am trying to create a music streaming app.
So far it works just fine.
I am using the
MediaPlayer.create(thisContext, Uri.parse(PATH_TO_STREAM));
convenience method to prepare the infinite stream (24x7 mp3 stream).
It hangs for just a few seconds on this call which I have neatly tucked into my startPlaying() method.
The button doesn't show it's getting clicked until after the stream starts playing so at first the user is left wondering if they tapped the button or missed.
So I want to update a TextView label next to the button that says "Wait..." or "Buffering" etc. then clear it after the stream starts so the user knows they pressed the button OK.
Even if I step through this in debug the label doesn't update until after the onClick is finished. I can comment out the last line that clears the label text and can see it set to "Buffering..." OK. But only after it exits the onClick. Is this a limitation of using the media player create() method?
final Button startbutton = (Button) findViewById(R.id.Button01);
this.tvBuffering = (TextView) findViewById(R.id.tvBuffering);
startbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tvBuffering.setText("Buffering...");
//do something like invalidate() here??
startPlaying(); //blocks here for a few seconds to buffer then plays.
tvBuffering.setText(" "); //clear the text since it's playing by now.
}
});

It's not such a great idea to intentionally include that sort of delay in the UI, because that will block just about anything the user tries to do for those few seconds. I'm assuming that your startPlaying() includes a call to prepare(), as well as start(). When taking data from a source that won't be immediately available (such as a stream), you should use prepareAsync() instead, which will start preparation and return immediately instead of blocking until preparation is complete.
You can attach a callback to your MediaPlayer to then take action once preparation has completed through a MediaPlayer.OnPreparedListener
Here's a simple example. Note that your OnClickListener can stay the same, as long as you change the prepare() in the startPlaying() method to prepareAsync() and remove the start() call from startPlaying().
startbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tvBuffering.setText("Buffering...");
startPlaying(); //which should call prepareAsync() instead of prepare()
//and have no call to start()
}
});
mYourMediaPlayer.setOnPreparedListener( new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
start();
tvBuffering.setText(" ");
}
});

Related

Should I release or reset the MediaPlayer?

I haave my own Custom Adapter Class called WordAdapter, and I am using a Media Player(named pronounce-global variable in the WordAdapter class). I have different activities in which each list item has a linear layout(named as linearLayout). I am setting onClickListener to it so that when the Linear Layout is clicked, a sound file is played. On completion of playing that sound, I want to free off any unwanted memory. But I do not know if I should use release() or reset(). I have checked previous questions asked on SO before, but I don't think it provides precise explanation for my situation so as to use which method.
NOTE: I should be able to play other audio files after this one too (After completing playing this audio file, when I click on other items in the same activity, I should be able to get the sound.)
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pronounce = MediaPlayer.create(context, currentWord.getPronounceResourceID());
pronounce.start();
pronounce.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer player) {
//pronounce.release();
//pronounce.reset();
}
});
}
});
Do a reset before a release, but I suspect that only release is needed.
This might be easier to manage:
public void onClick(View view) {
if (pronounce != null) {
pronounce.reset();
pronounce.release();
pronounce = null;
}
pronounce = MediaPlayer.create(context, currentWord.getPronounceResourceID());
pronounce.start();
}
The reset method will simply stop any media and send the MediaPlayer instance back to the idle state. Exactly in the same state when it was created.
The release method destroys the media player and frees the majority of the unmanaged resources. When you call release, you should set the instance variable to null so that the remainder of the object is a candidate for garbage collection.
You might have some better performance if you just use reset and then reuse the existing mediaplayer instance on subsequent clicks.

Android Mediplayer not playing music

I am trying to play a song that is in remote server and is in this link. You also can check the song. but as per what i have coded the song is not getting played from the remote server.
Button b = (Button) findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try{
mySong = new MediaPlayer();
mySong.setDataSource("http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3");
mySong.setAudioStreamType(AudioManager.STREAM_MUSIC);
mySong.prepareAsync();
mySong.start();
}
catch(Exception ee){
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(ee.getMessage());
}
finally{
mySong.reset();
mySong.release();
}
}
});
are you serious?
You are starting it just to reset and release it instantly?find the wrong logic!
Or do you think the finally statement will be executed after the song is played through?
You call prepareAsync() in your code. Because you are preparing asynchronously, you're going to receive a callback called onPrepared(MediaPlayer) after you've declared that your Activity implements MediaPlayer.OnPreparedListener. It is here that you should be calling mySong.start(). Calling it right after prepareAsync would most likely cause an IllegalStateException to occur because the MediaPlayer isn't prepared yet. Finally, you'll want to set a MediaPlayer.OnCompletionListener so you can release the MediaPlayer there instead of the finally block. Also, resetting the MediaPlayer and releasing is redundant. If you're going to release it right away, there's no reason to reset it.

How to detect when video has stopped playing and perform action thereafter(Android)

In my program when user clicks on imagepreview video starts running.Video is played in same actvity in which images are.When video is played images are made invisible.I want that when video stop it should disappear and images should be visible.I tried using isPlaying() method but doesn't work out as expected.If I put isPlaying() method inside onClick() then the action inside isPlaying() is performed even before the video is started and if i place it ouside setOnClickListener() then this method doesn't execute when video is stopped.Plzz help me with code
imgPreview.setOnClickListener(new View.OnClickListener() { //clicking on first imageView
#Override
public void onClick(View v) {
imgPreview.setVisibility(View.GONE);
imgPreview2.setVisibility(View.GONE);
videoPreview2.setVisibility(View.VISIBLE);
videoPreview2.setVideoPath(fileUri.getPath());
videoPreview2.start();
}
});
if(videoPreview2.isPlaying()==false){
imgPreview.setVisibility(View.VISIBLE);
imgPreview2.setVisibility(View.VISIBLE);
videoPreview2.setVisibility(View.GONE);
}
Have you tried videoview's setcompletion listener. See the docs.
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
//make image visible here
}
});

Playing a downloaded song

I'm new to android so I'm having a problem thinking of a solution. First thing I do is change activities to a different screen, and while in the activity I download a song. I then return to MainActivity which is a MediaPlayer activity. Now, I'm a little confused on activity lifecycles, if I return to MainActivity, and run:
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
File song = new File(path, "SpaceJam.mp3");
That's in my onCreate, so basically I'm asking does onCreate run every time you return to an activity?
Second, I have a play/pause button:
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// check for already playing
if(mp.isPlaying()){
if(mp!=null){
mp.pause();
// Changing button image to play button
btnPlay.setImageResource(R.drawable.play_t); }
}else{
// Resume song
if(mp!=null){
mp.start();
// Changing button image to pause button
btnPlay.setImageResource(R.drawable.pause_t);
}
}
}
});
The problem is, I don't want to do use:
mp.setDataSource(path+"/"+fileName);
mp.prepare();
mp.start();
On my play button, because it'll reinitialize the song every time. What's the best way to go about doing this?
Thanks
That's in my onCreate, so basically I'm asking does onCreate run every time you return to an activity?
No. onResume() or onStart() would be good choices but you should read the Activity life cycle documentation and choose accordingly.
http://developer.android.com/training/basics/activity-lifecycle/index.html
On my play button, because it'll reinitialize the song every time. What's the best way to go about doing this?
To save the current position, e.g. in onPause()
Mediaplayer.pause();
length=Mediaplayer.getCurrentPosition();
To resume, e.g. in onResume()
Mediaplayer.seekTo(length);
Mediaplayer.start();

MediaPlayer force close after consecutive clicks

I've made a button and when you click it, it gives away a short sound(Max one second-sound). But after I've clicked the button about 20 times in a row I get force close..
The code is:
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.buzzer);
mp.start();
}
});
I've tried with mp.stop(); but then my sound stops after it have been played half of the time...
One more thing, does anyone know how to "prepare" the sound when I click? Because the sound gets delayed with some milliseconds the first time I press the button.
Create a MediaPlayer member variable and initialize it in onCreate() the same way you are doing in the listener. Then in the listener just use this code:
if(mPlayer.isPlaying()) {
mPlayer.stop();
}
mPlayer.start();
Then call mPlayer.release() in your finish() Activity. My guess is that since none of your MediaPlayer instances are being released, it's running out of memory to use.
The official document for MediaPlayer is actually incredibly descriptive and helpful:
http://developer.android.com/reference/android/media/MediaPlayer.html

Categories

Resources