Mediaplayer stops in android after 30 clicks - android

I've seen other posts on this but I cant figure out problem.
So I'm designing a calculator and all the numbers have one onclick method and all the operators have different . I have a method playSound() where the code is:
public void playSound(){
MediaPlayer mp= MediaPlayer.create(this, R.raw.btn);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
if(mp.isPlaying())
{
mp.stop();
mp.reset();
}
mp.start();
}
I've tried release to. Can anyone let me know the efficient way to write this.
I call this method inside the onclick methods. But after around 30 clicks it stops. I've also tried to create MediaPlayer global but it still stops. I've read mediaplayer is actually costly so we can use soundpool. But even soundpool is deprecated. Any help?

Implement onComplition() Listener , and in that listener you can call release method
You created multiple instances of mediaplayer and not release mediaplayer instanace thats why issue is came
After you release called your issue will be resolved

Initialize the MediaPlayer as a class attribute:
MediaPlayer media = MediaPlayer.create(this,R.raw. btn);
In the playSound() method:
public void playSound(){
setVolumeControlStream(AudioManager.STREAM_MUSIC);
mp.reset();
mp.start();
}

Related

Android media player: "start called in state 0"

I'm trying to get a simple sound to play. The sound plays on the emulator but not on the phone. It says
start called in state 0
and
Error (-38,0)
Here's what I've tried so far:
MediaPlayer secondSound;
MediaPlayer minuteSound;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
secondSound = new MediaPlayer();
secondSound = MediaPlayer.create(this, R.raw.everysecondsound);
minuteSound = MediaPlayer.create(this, R.raw.everyminutesound);
secondSound.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer player) {
player.start();
}
});
minuteSound.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer player) {
player.start();
}
});
}
Later in the program, the following methods are called:
minuteSound.start();
secondSound.start();
On the emulator, this works fine even without the .setOnPreparedListener part. The emulator is running API 22, the phone is running API 19. Is there a different way to use the media player in the older APIs?
When you call MediaPlayer.create(), that automatically calls prepare() for you, as seen in the source code. As per the state diagram in the MediaPlayer documentation:
This puts you into the Prepared state. At that point, when you call start(), you move into the Started state. After playback completes, you'll be in the Playback Completed state. If you'd like to play your sound again, you have to call create() again, or call stop() and prepare() again.
You'll find SoundPool more appropriate for short tracks you want to play repeatedly.
First of all, I think you have to declare the minute MediaPayer (as you did with the second), this way: minuteSound = new MediaPlayer();
Try this and return. If it doesn't work, maybe you will have to release the MediaPlayer before calling it again.
The problem was the file format for my sound files. They were originally 96000Hz wave files, I changed them to 44100Hz MP3 files and then everything worked. I removed the .setOnPrepareListener part since it worked without it.

What means the message "internal/external state mismatch corrected" at the MediaPlayer?

I work with a MediaPlayer and set the state of the player often programmatically like for example:
if(mp.isPlaying()) {
mp.pause();
animationPausedMusic();
}
private void animationPausedMusic() {
// Changing button image to play button
btn_play.setBackgroundResource(R.drawable.play);
... // more code
}
But sometimes the logcat gives me the message:
"internal/external state mismatch corrected"
And then the play and pause function is not working anymore.
What does this message mean? And how can I solve it?
After going through the android's native framework for media player I found that in source file mediaplayer.cpp inside function bool MediaPlayer::isPlaying() The developer is checking if the currentState of media player is in STARTED state and yet the media player is not playing any media, so it tries to change the state to PAUSED state so that the state consistency should be maintained for API users.(and here is where he is printing the message "ALOGE("internal/external state mismatch corrected");")
Now If you go through the media player state diagram below:
You would notice that this may happen when the MediaPlayer moved to 'STARTED' state after a call to start() and at this time for some obscure reason has not yet started the playback and you fire a MediaPlayer.isPlaying() method call , The Framework treat this as state inconsistency and moves to 'PAUSED' state and that's why you cannot see anything playing further.
However, if someone has some better understanding please share your thoughts!
I ran into this recently, and like some other questions say, it's this bug (marked obsolete alas)
https://code.google.com/p/android/issues/detail?id=9732
I found this error occurs when playing a MIDI file, but only sometimes. It happens when mp.isPlaying() is called quickly after mp.start()
If you can manage to not call mp.isPlaying() for a little bit, the error doesn't occur. In my case, a 10th of a second or so made the difference between getting the error or not. It's awkward, but it works.
e.g.
//setting a new track
mp.setDataSource(path);
mp.prepare();
mp.start();
//calling mp.isPlaying() here or shortly after starts the problem
//since we know it's playing, we can store that state, or call
updateUiPlaying(); //eg instead of updateUi();
//or just call some code here that takes more time first
updateScaledImages(); //something that might take time
Log.v(TAG, "mp.isPlaying = " + mp.isPlaying()); //now isPlaying() shouldn't cause that error
Also, I put a check in when I pause later.
mp.pause()
if(mp.isPlaying()){
//shouldn't be playing, must be in error
mp.stop();
mp.release();
mp = new MediaPlayer();
//any other initialization here
}
Though the problem doesn't occur if there is a wait before calling isPlaying()
Apparently there is more than one cause of this message. The following solution worked for me. It may or may not work for you. I called the method MediaPlayer.reset() immediately after instantiating the MediaPlayer object:
MediaPlayer mp = new MediaPlayer();
mp.reset();

If mp.isPlaying() causes app to crush

I am using a MediaPlayer. Somewhere inside my code I use:
if (mp != null) {
System.out.println("This");
if (mp.isPlaying()) //1
System.out.println("That"); //2
}
And as I run it, the app for some reason stops from working. If I delete the //1 and //2 lines, is runs normally and it prints "This". But why, I just want to check if mp is playing or not
as you can see on Android MediaPlayer documentations
public boolean isPlaying ()
Added in API level 1 Checks whether the MediaPlayer is playing.
Returns true if currently playing, false otherwise Throws
IllegalStateException if the internal player engine has not been
initialized or has been released.
check if you are initialising the MediaPlayer correctly and that you haven't released it before calling isPlaying().
please mark it as correct answer if that helped you.

Using Mediaplayer to replay the same file

Im hoping you can provide some guidance. I created a 'final' instance of a mediaplayer (mp1) and on a button click it plays a mp3 file. I then need to stop the file when I click a second button. This works fine until I try to play the file again - nothing happens. I think that because the mp1 instance is 'final', when I stop it, it stops for good until I relaunch the app. I dont want to pause the file, I want to stop it and then restart it afresh. Any ideas welcome. I tried putting the mp1 creation within the button. This worked until the app crashed - probably because multiple mediaplayer creations used all the device memory?
Thanks!!!
// const mediaplayer
mp1 = MediaPlayer.create(getApplicationContext(), R.raw.mysound);
...
// in button 1
if (radSound1.isChecked()) {
radSound2.setChecked(false); // ...set radiobutton 2 to false
mp1.start(); // ...play the mp3 file
}
...
// in button 2
if (mp1 != null){
mp1.reset();
//mp1.setDataSource();
// mp1.prepare();
}
Follow the state diagram here. stop() stops playing and puts you in stopped state. Before starting to play for the next time, you should call prepare() and then start() again.
So in button 1, you should call start() and in button 2, you should call stop() and prepare(). The initialization is fine, do it once and keep it outside the buttons.
Also accept answers to your questions including this so that people like me will be more motivated to reply to them in the future.

MediaPlayer callbacks not firing after calling prepareAsync() from a Service

I'm working on writing a small app that will stream mp3 files. I'm using the NPR code, but having a strange problem with mediaPlayer.prepareAsync().
I'm using a trimmed down version of the PlaybackService from the NPR app, which is getting started correctly. I am getting a reference to the service inside an OnClick handler inside an Activity, and calling listen() with the URL to the MP3 stream. The following (simplified) code is from my PlaybackService:
public void listen(String url) throws IllegalArgumentException, IllegalStateException, IOException {
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
}
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnInfoListener(this);
mediaPlayer.setOnPreparedListener(this);
synchronized (this) {
mediaPlayer.setDataSource(url);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepareAsync();
}
}
// ... lots of other code
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(LOG_TAG, "Prepared");
play();
}
I have the other callbacks defined as well. I can see from LogCat that the MediaPlayer is loading the stream and buffering, as I see the following messages:
AwesomePlayer I calling prefetcher->prepare()
AwesomePlayer I prefetcher is done preparing
But my onPrepared method never gets called. If I add a timer and try to call play() on the MediaPlayer at some point after I see the above log messages, the media players plays, so it is indeed entering into the Prepared state.
If I replace the call to prepareAsync() with prepare(), the player just works. This is all on 2.2, which I have been reading seems to have some issues, but the problem I'm having doesn't seem related, as the stream works fine when prepare() is used.
I did notice that the Content-Length on the the stream is quite large (450MB), but since I can call play on the Media Player without getting an exception, it appears to be handling this OK.
The only other change is that in the NPR app, the service is being bound to and the playback started from inside a View object (while in my app, this happens inside an Activity).
Any thoughts on what I could be doing wrong?
Make sure you have created the mediaplayer in a thread that has a looper, which is required for the callbacks to work properly.

Categories

Resources