android mediaplayer: how to get player status except isPlaying? - android

mediaplayer has isPlaying,but only this. How can I know player is isPaused or isStopped ?
Playback can be paused and stopped, and the current playback position
can be adjusted. Playback can be paused via pause(). When the call to
pause() returns, the MediaPlayer object enters the Paused state. Note
that the transition from the Started state to the Paused state and
vice versa happens asynchronously in the player engine. It may take
some time before the state is updated in calls to isPlaying(), and it
can be a number of seconds in the case of streamed content. from:
MediaPlayer.html#isPlaying

All the methods you saw are the only ones that are available. For other things, you can use:
try {
//command
} finally {
//only called once the calls in the try clause are completed
}

As of now, there is no method available in MediaPlayer API to get the current status other than playing or not.
MediaPlayer.isPlaying() method returns true if currently playing, false otherwise and may throw IllegalStateException if called in invalid state.
if(mPlayer.isPlaying()){
// MediaPlayer is in play state
}
else{
// MediaPlayer is not in play state
}
I recommend you to keep an enum flag to identify each state, for example
public enum PlayerStates{PAUSED,STOPPED,PLAYING};
PlayerStates state;
...
public void pause(){
mPlayer.pause();
state=PlayerStates.PAUSED;
}
public void play(){
mPlayer.start();
state=PlayerStates.PLAYING;
}
public void stop(){
mPlayer.stop();
state=PlayerStates.STOPPED;
}
// returns the current state of MediaPlayer
public PlayerStates getState(){
return state;
}
I hope this helps you in someway.

Related

Audio is playing twice in Android Media Player

In my application I'm having a method responsible for playing file placed under raw directory. But when Ever I call that function in my onResume() method, sound is played twice. Even I have googled and tried different solutions. even by checking mediaPlayer.isPlaying() and then stopping the MediaPlayer instance but still didn't get any help.
private void EnglishSound(){
if(mediaPlayer1!=null){
if(mediaPlayer1.isPlaying()){
mediaPlayer1.stop();
}
mediaPlayer1.reset();
mediaPlayer1.release();
}
mediaPlayer1 = MediaPlayer.create(this, R.raw.p012);
mediaPlayer1.start();
}
public void onResume() {
super.onResume();
EnglishSound();
}
and EnglishSound() is called no where else in the whole activity. Even have tried debugging but it never enters the if block containing isPlaying().
Try to release onPause()
public void onPause() {
super.onPause();
if(mediaPlayer1 != null)
mediaPlayer1.release();
}

Why does my MediaPlayer stop working if I "interrupt" it?

I want my button to be "spammable". This means that if I tap on the button repeatedly the MediaPlayer starts all over again.
firstButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (firstTextView.getText().equals("Hello world!")) {
firstTextView.setText("You clicked!");
} else {
firstTextView.setText("Hello world!");
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.start();
}
});
When I interrupt the MediaPlayer when it is playing, it stops and never starts again. Why?
EDIT: The problem is that I called stop(). Thanks for pointing that out.
As per the documentation, you need to re-prepare the MediaPlayer (emphasis mine):
Once in the Stopped state, playback cannot be started until
prepare() or prepareAsync() are called to set the MediaPlayer object
to the Prepared state again.
Seems you are stopping the player because you are calling mediaPlayer.stop() this makes the MediaPlayer state to go in Stopped state. It will continue to play again when you call prepare() or prepareAsync() and has its preparation callback fired to start the playing media.

Is my code sufficient to prevent MediaPlayer leakage?

In my Activity I have the following:
private Set<MediaPlayer> mediaPlayers;
public void onSomeEventInMyActivity()
{
// play sound
MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.my_sound);
mediaPlayers.add(mediaPlayer);
mediaPlayer.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
mp.release();
mediaPlayers.remove(mp);
}
});
mediaPlayer.start();
}
#Override
protected void onStart()
{
super.onStart();
mediaPlayers = new HashSet<MediaPlayer>();
}
#Override
protected void onStop()
{
super.onStop();
for (MediaPlayer mediaPlayer : mediaPlayers)
{
if (mediaPlayer.isPlaying())
{
mediaPlayer.stop();
}
mediaPlayer.release();
}
}
Is this code sufficient or will it lead to MediaPlayer leakage? Are my implementations of onStop and onStart necessary, or can I just rely on calling release in onCompletion?
I did my code this way because I assume onStop() could be called while a MediaPlayer is playing, so I need to call release because onCompletion won't be called yet. I'm just guessing that this is right, so correct me if I am wrong.
I also read that onStop is not called in low-memory situations - what to do then?
An onStop() routine is needed if the mediaPlayer is expected to stop when the activity becomes invisible. Otherwise, the mediaPlayer goes on playing. On older OSs, Gingerbread and earlier, the activity can execute onPause() - say, when a phone call arrives - and, in extreme circumstances, be destroyed without ever executing onStop(). I don't know what would happen to a running mediaPlayer then. However, if there is a phone call coming in, it might be an idea to stop the mediaPlayer in onPause()! Later OSs always pass through onStop() before destroying the Activity. Calling mp.release() on the mediaPlayer after stopping it, in either onPause() or onStop(), is correct.
It's also desirable to remove the reference to the player held in mediaPlayers, which doesn't happen in onStop() above. Something like:
#Override public void onCompletion(MediaPlayer mp) {
mp.stop(); // It's always safe to call stop()
mp.release(); // release resources internal to the MediaPlayer
mediaPlayers.remove(mp); // remove reference to MediaPlayer to allow GC
}
and then
#Override public void onPause() {
for (Object mediaPlayer : mediaPlayers.toArray()) {
onCompletion((MediaPlayer) mediaPlayer); // stop, release, and free for GC, each mp.
}
super.onPause();
}
(I originally had for (Object mediaPlayer : mediaPlayers) {} in the above code but omfeddf345mnof32nisd45fgoq2t pointed out that I would be modifying a set while iterating over it. Thanks for the correction!)
Only callback guaranted to be called is onPause(), so you may leak this media player in some situations. In case stopping player on activity pause is not acceptable you should use service, and watch for certain events ( like incoming phone call etc )

How to stop media player properly , android

I have created a list of songs on click on the song i am able to play the song using MedaiPlayer. While one song is playing if the user clicks another song then i am stopping the media player and starting the player again. But I am getting illegalstateexception in reset(). Here is the code where I am getting the exception. How to stop a player properly? also why am i getting this exception. How to avoid it?
public void stopPlayer() {
try {
if (player != null) {
// Log.e("Trying to Stop "," Player ");
player.stop();
player.release();
player.reset();// causes IllegalstateException
player = null;
}
} catch (Exception e) {
player = null;
playerStatus = false;
e.printStackTrace();
}
}
try this :
player.reset();
player.release();
and also have a look at media player state diagram.
If you want to play again ,then use player.reset(),
player.release() means that it releases the player object so you have to re-intialise the player. So first you use reset() and then release(). release() is used when your player object no longer working. When your activity destroys release() method to be used for good practice.
Whenever you want to stop it:
if(player!=null)
{
if(player.isPlaying())
player.stop();
player.reset();//It requires again setDataSource for player object.
}
Whenever your player no longer to be needed:
if(player!=null)
{
if(player.isPlaying())
player.stop();
player.reset();//It requires again setDataSource for player object.
player.release();
player=null; // fixed typo.
}
Though the accepted answer works, This is a better way to achieve the task
private void stopSong() {
if(mediaPlayer!=null) {
if(mediaPlayer.isPlaying()) {
mediaPlayer.reset();// It requires again setDataSource for player object.
mediaPlayer.stop();// Stop it
mediaPlayer.release();// Release it
mediaPlayer = null; // Initialize it to null so it can be used later
}
}
}
Are you planning on reusing the player again, or are you done with the player? If you're done with the player, call release() and not reset(). If you plan on reusing the player, call reset() and not release().
reset() resets the player to its uninitialized state.
release() frees all resources associated with the player.
The Media Player State Diagram shows, and also states:
Calling stop() stops playback and causes a MediaPlayer in the Started, Paused, Prepared or PlaybackCompleted state to enter the Stopped state.
Once in the Stopped state, playback cannot be started until prepare() or prepareAsync() are called to set the MediaPlayer object to the Prepared state again.
That means, that after calling stop(), we should call prepare() on the same audio file if we wish to play it again. Otherwise calling start() again won't do anything.
As prepare() might throw exception, we should wrap it in a try-catch block, like this:
public void stopAudio(View view) {
mplayer.stop();
try {
mplayer.prepare();
} catch (IOException e) {
Log.e("stopAudio", "Unable to prepare() mplayer after stop()", e);
}
}

How to turn off my media service for an incoming call? My AudioManager is not working

I'm trying to setup my audio playing app to stop playback if there is an interruption. I followed directions in Android SDK Developer notes about setting up an AudioFocusHelper like so:
public class AudioFocusHelper implements AudioManager.OnAudioFocusChangeListener {
AudioManager mAudioManager;
Media_Service mService;
Context mContext;
public AudioFocusHelper(Context ctx, Media_Service svc) {
mAudioManager = (AudioManager) ctx.getSystemService(Context.AUDIO_SERVICE);
mService = svc;
}
public boolean requestFocus() {
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
}
public boolean abandonFocus() {
return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
mAudioManager.abandonAudioFocus(this);
}
#Override
public void onAudioFocusChange(int focusChange) {
// let your service know about the focus change
mService.AudioFocus(focusChange);
}
}
and I have my audio player running in a service as they suggest. I have this method in my audio service to respond to Audio Focus changes to pause the playback but its not working -- I don't know how to test this in the vm debugger so I can't really see what is happening on an incoming call. It doesn't appear to get called since I told it to popup toasts:
public void AudioFocus(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN: // resume playback
if (mMediaPlayer == null)
initMediaPlayer();
else if (!mMediaPlayer.isPlaying())
mMediaPlayer.start();
//mMediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS: // Lost focus for an unbounded amount of time: stop playback and release media player
if (mMediaPlayer.isPlaying()) {
Toast.makeText(this,
"Playback interrupted by focus loss", Toast.LENGTH_SHORT).show();
mMediaPlayer.stop();
}
mMediaPlayer.release();
mMediaPlayer = null;
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: // Lost focus for a short time, but we have to stop
// playback. We don't release the media player because playback
// is likely to resume
if (mMediaPlayer.isPlaying()) {
Toast.makeText(this,
"Playback paused by focus loss (transient)", Toast.LENGTH_SHORT).show();
mMediaPlayer.pause();
}
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // Lost focus for a short time, but it's ok to keep playing
// at an attenuated level
if (mMediaPlayer.isPlaying()) {
Toast.makeText(this,
"Playback paused by focus loss (duck)", Toast.LENGTH_SHORT).show();
mMediaPlayer.pause();
//mMediaPlayer.setVolume(0.1f, 0.1f);
}
break;
}
}
I can post more of the code if necessary, it seems like I'm posting a lot of code already and I don't want to post an excessive amount. It looks to me like my onAudioFocusChange just isn't getting called. I am running this on Android 2.2 (minSDK 8) since these feature is not supported before 2.2. Searched hi and low for tips and I find very little about this topic at all so I'm hoping somebody out there can give me some clues.
I had this same issue, remember you need to call the requestFocus() method when you start playback and abandonFocus() when you are done.
I think this may help with generating incoming calls through DDMS: Fake Incoming Call Android
Hopefully, you can debug your application with this.

Categories

Resources