I have problems with my app because multimedia sound is heard when the app is in background
I have defined my Media player like this;
private void playLocalAudio(int R1)throws Exception
{
MediaPlayer mediaPlayer = MediaPlayer.create(this,R1);
mediaPlayer.start();
}
For calling PlayLocalAudio I do:
try{
playLocalAudio(R.raw.fartw1);
}
catch (Exception e) {
e.printStackTrace();
}
}});
But I am not able to call correctly MediaPlayer.Stop()
I am trying:
public void onPause()
{
super.onPause();
mediaplayer.stop();
}
But it doesn't work. Could you help me?
I'm guessing that your code has a class variable mediaPlayer that's not visible in your example. In that case you have variable shadowing, because you're instantiating a new mediaPlayer in playLocalAudio and that instance is not visible inside the pause method. So stop is never called. Remove the MediaPlayer class name from the declaration in playLocalAudio.
Related
I am having some trouble using the android MediaPlayer in a non activity class, always a context error. Here is the bugged line:
MediaPlayer Shoot = MediaPlayer.create(this, R.raw.shot);
Now I know I cant use "this" in a service, but all the other stuff I tried kept giving bugs.
any suggestions?
You are too luck because in the last two days I have develop an app that uses MediaPlayer inside a background Service ;)
You can simply retrieve an instance of your MediaPlayer using the next line:
MediaPlayer mediaPlayer = new MediaPlayer();
Then you can set all listener and play song that you want.
Edit 22th april 2012
To set listeners (an example):
mediaPlayer.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO notify error to user or play next song
return true;
}
});
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// TODO Notify to user the completion of song or play next song
}
});
To start and play song you have to do something like this:
try{
mediaPlayer.setDataSource(mSongUrl);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
// Starting media player
mediaPlayer.start();
Why don't you just pass the context reference to the constructor of your non activity class.
and then from there save it and pass it to where it is needed.
Make sure your context reference no longer remain live after its use. Else it will gonna cause memory issue.
I am using the Android MediaPlayer class and trying to write a testcase which verifies that the onCompletion method is called.
I use it to play the next track after the previous one is finished.
When I run the app using the emulator (2.1 or 4.0) the onCompletion method is called and the next track starts playing, but in the testcase it is not.
Here is the simplified code:
public class MediaPlayerControllerTest extends AndroidTestCase implements OnCompletionListener {
public void testContinuePlayNextTrack() {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
try {
mediaPlayer.setDataSource("/mnt/sdcard/5749/01.mp3");
mediaPlayer.prepare();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaPlayer.start();
}
#Override
public void onCompletion(MediaPlayer mp) {
System.out.println("ON COMPLETION!!!!!");
}
}
The code above is normally part of a class MediPlayerController which is used in the app and the test, so it's the same class. I broke the problem down to the few lines of code above.
This cost me a lot of hours. I hope someone has a solution!
Thanks a lot!!!
I have encountered this problem, and nothing was working for me. From the official Site (click me) for the MediaPlayer one can find the following sentence:
In order to receive the respective callback associated with these listeners, applications are required to create MediaPlayer objects on a thread with its own Looper running (main UI thread by default has a Looper running).
I was a bit lost, as there was no hint for this need on in the API for onCompletionListener himself.
I think the problem is that your test case is no longer running when the MediaPlayer finishes playing the mp3. So your solution is to keep the test case alive until the onCompletion() is fired.
I had a similar issue when playing a file from an IntentService. The Service was being destroyed before the callback was initiated.
Actually, the reason is that the MediaPlayer is a local variable. After the testContinuePlayNextTrack() is finished, the MediaPlayer is collected by GC. So the fix is easy, make your MediaPlayer a member of the class.
public class MediaPlayerControllerTest extends AndroidTestCase implements OnCompletionListener {
MediaPlayer mediaPlayer = new MediaPlayer();
public void testContinuePlayNextTrack() {
mediaPlayer.setOnCompletionListener(this);
try {
mediaPlayer.setDataSource("/mnt/sdcard/5749/01.mp3");
mediaPlayer.prepare();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaPlayer.start();
}
#Override
public void onCompletion(MediaPlayer mp) {
System.out.println("ON COMPLETION!!!!!");
}
}
In my onCreate method i check to see whether a media player is playing and if it is a shut it down
if(mediaplayer.isPlaying()==false)
try {
playAudio(path);
} catch (Exception e) {
e.printStackTrace();
}else{
mediaplayer.stop();
mediaplayer.reset();
}
primarySeekBarProgressUpdater();
}
my play audio method is
private void playAudio(String url) throws Exception{
mediaplayer.setDataSource(url);
mediaplayer.prepare();
mediaplayer.start();
}
i also initialize my media player before the onCreate method. The problem is my media player won't shut down instead when a user clicks on a new song in the list view class it creates this class and plays both media players at the same time the old one continues playing.
Ok, so I assume you have a ListActivity with full of songs, and users click to any of those, it will move to a new Activity to play the song, in which the song information is passed through the Intent.
First of all, you need to read and remember Activity Lifecycle: http://developer.android.com/reference/android/app/Activity.html
Secondly, to your problem, according to the lifecycle, everytime users click to a song on the list, then it will create a new Activity to play the song, that means it creates a new MediaPlayer object as well. Hence, you can see many songs playing as much as you select the songs from the list.
What you need to do is to handle the MediaPlayer object when you close the music-playing screen to return to your song list.
MediaPlayer mPlayer = null;;
public void onCreate() {
// init mediaplayer here
mPlayer = ...
}
public void onDestroy() {
// release object
if( mPlayer != null ) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
}
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);
}
}
I have a audio player app, where there is a Main activity that shows 3 audio sample urls. On click on one, it goes to a Details Activity, which has a play and pause button, to start and pause the audio.
My problem is that, when I start the Main activity, and say click on audio 1, I hit play on Details activity. This starts the MediaPlayer and the audio starts to play. When I go back to the Main activity, the audio is still playing, which is what I want. Now, when I click on audio 1 again, and go to Details Activity and hit play again, there seems to be a new MediaPlayer starting the audio. So I have 2 tracks playing together!
Is there a way I can have only one MediaPlayer instance at any given time?
Thanks
Chris
You should consider the Singleton pattern. Make a class MyPlayer that has a static method getMediaPlayer() that returns the same instance of MediaPlayer each time called.
Singleton Class
public final class MySingleton extends Application {
static MediaPlayer instance;
public static MediaPlayer getInstance() {
if (instance == null)
{
instance = new MediaPlayer();
}
return instance;
}
}
Adapter Where your List
Initialize Your Singleton Class One time in Constructor
private static MediaPlayer mMediaPlayer = MySingleton.getInstance();
if (mMediaPlayer.isPlaying()) {
try {
mMediaPlayer.reset();
mMediaPlayer.stop();
mMediaPlayer.setDataSource(mainActivity, Uri.parse(songsarraylist.get(position).getPath()));
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (Exception e) {
Toast.makeText(mainActivity, "Catching", Toast.LENGTH_SHORT).show();
}
} else {
try {
mMediaPlayer.setDataSource(mainActivity, Uri.parse(songsarraylist.get(position).getPath()));
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}