Android: Stop song before playing a new one. - android

I try to play a song when I receive an SMS,
when I receive 2 SMS then song play simultaneously.
Thanks for your help
Runnable stopPlayerTask = new Runnable(){
#Override
public void run() {
mPlayer.stop();
}
};
if(mPlayer.isPlaying()){
mPlayer.stop();
}else{
mPlayer.seekTo(startime);
mPlayer.start();
mPlayer.setLooping(true);
}
Handler handler = new Handler();
handler.postDelayed(stopPlayerTask, endtime);

If I understand your intended use of the mediaPlayer correctly, you should be requesting Audio Focus from the Android system. Therefore, you can have the mediaplyer wrapped in a service that implements "AudioManager.OnAudioFocusChangeListener". If you implement the callbacks correctly for your application, then the song should never play simultaneously.
Note that Android requires an API level of at least 8 to use AudioManager
Here is the reference in the documentation for this:
http://developer.android.com/guide/topics/media/mediaplayer.html

Use mPlayer.reset(); after mPlayer.stop();
This will reset all initialization ex: track URI etc so will have to set again track URI before mPlayer.start();
This will let only new and one track play at a time and will stop & reset previous track completely.

Related

Android Playing audio file (.wav)

Need to play some .wav file but only some part of it (from start).
For example I have test.wav file and it is 10 seconds I want to play only 0-5 seconds.
I try to use seekTo method but it doesn't help my app was crashed.
AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.test);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_SYSTEM);
mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mMediaPlayer.setOnPreparedListener(mOnPreparedListener);
mMediaPlayer.setOnCompletionListener(mMediaPlayerCompletionListener);
mMediaPlayer.seekTo(5000);
mMediaPlayer.prepare();
You could just stop playing after set amount of time (5 sec in your case). There are many ways to do that, one could be:
final Handler handler = new Handler();
//create a runnable that will be called to stop playback
final Runnable runnable = new Runnable() {
#Override
public void run() {
//stop playback, make sure mMediaPlayer is declared as a field
//in the class where it's used
mMediaPlayer.stop();
}
};
//post a job for handler do be done in 5 seconds
handler.postDelayed(runnable, 5 * 1000);
you can't seek before you call prepare, i am not sure whether you can do that before actually calling MediaPlayer.play() to be honest you need to check that up but for sure prepare goes first.

MediaPlayer stops working after 30 uses?

I'm trying to write a function to play a short sound (in /res/raw) in my program, called at effectively random times throughout the program. So far I have this function:
public void playSound() {
MediaPlayer mp = new MediaPlayer();
mp = MediaPlayer.create(this, R.raw.ShortBeep);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setLooping(false);
mp.start();
}
It works fine for awhile, but after exactly 30 plays of the sound, it stops making sound.
According to the Docs
... failure to call release() may cause subsequent instances of MediaPlayer objects to fallback to software implementations or fail altogether.
When you are done with it call mp.release() so that it can release the resources. I don't know what the limit is and I'm sure it depends on many factors. Either way you should be calling this function on your MediaPlayer object, especially if it will be used more than once.
I've just solved the exact same problem, but I'm using Xamarin. I ended up changing from holding on to a MediaPlayer instance for the lifetime of the activity to creating an instance each time I want to play a sound. I also implemented the IOnPreparedListener and IOnCompletionListener.
Hopefully you can get the idea despite it being C# code
public class ScanBarcodeView :
MvxActivity,
MediaPlayer.IOnPreparedListener,
MediaPlayer.IOnCompletionListener
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.ScanBarcodeView);
((ScanBarcodeViewModel) ViewModel).BarcodeScanFailed += (sender, args) => PlaySound(Resource.Raw.fail);
((ScanBarcodeViewModel) ViewModel).DuplicateScan += (sender, args) => PlaySound(Resource.Raw.tryagain);
}
private void PlaySound(int resource)
{
var mp = new MediaPlayer();
mp.SetDataSource(ApplicationContext, Android.Net.Uri.Parse($"android.resource://com.company.appname/{resource}"));
mp.SetOnPreparedListener(this);
mp.SetOnCompletionListener(this);
mp.PrepareAsync();
}
public void OnPrepared(MediaPlayer mp)
{
mp.Start();
}
public void OnCompletion(MediaPlayer mp)
{
mp.Release();
}
}
So, each time I want a sound to be played I create a MediaPlayer instance, so the data source, tell it that my Activity is the listener to Prepared and Completion events and prepare it. Since I'm using PrepareAsync I don't block the UI thread. When the media player is prepared the Start method on the MediaPlayer is called, and when the sound has finished playing the MediaPlayer object is released.
Before I made these changes I would get to 30 sounds played and it would all stop working. Now I've gone way past 30, also multiple sounds can be played simultaneously.
Hope that helps.

Android: Playing two sounds one after the other

I am trying to play two sound items, one after the other
MediaPlayer mp = null;
protected void produceErrorSound(int index) {
if (mp != null) {
mp.reset();
mp.release();
}
mp = MediaPlayer.create(this, index);
mp.start();
}
public void correctAnswerAndNext(){
produceErrorSound(R.raw.right1) ;
produceErrorSound(R.raw.right1) ;
}
but only second sound is produced.
is there any alternative approach?
I can't see any wait mechanism in your code.
You can use an onCompletionListener to receive a callback when your first MediaPlayer has finished playback. At that point you can start the second MediaPlayer.
An alternative way in Jellybean (and later versions) is to use the audio chaining functionality (i.e. setNextMediaPlayer) to automatically start another MediaPlayer as soon as the current one has finished playing. Something like this (I've omitted the calls to setDataSource etc for brevity):
mediaPlayer1.prepare();
mediaPlayer2.prepare();
mediaPlayer1.start();
mediaPlayer1.setNextMediaPlayer(mediaPlayer2);

Running a thread for some seconds

I am using a media player instance to play a music file.I want to play the song for certain time then stop playing.I'm using a thread with counter decrementing but some how tis not workin properly.
you have to use handler for that
try this
in your onCreate use this
//start media player
mp.start();
mTimer.sendMessageDelayed(new Message(),5*10000);
create a class in you activity class as
private MusicTimer mTimer = new MusicTimer();
private class MusicTimer extends Handler
{
#Override
handleMessage(Message msg)
{
onTimerExpire();
}
public void onTimerExpire()
{
//stop player here
}
}
make media player object member variable this will play that for five seconde then stop nthat
this is something you can do.. Play with media player normally and at the same Time initialise a handler and call its postDelayed method with interval you want.. and inside it stop the MEdia player.. Something like this..
new Handler().postDelayed(new Runnable(){
//stop playing
}, 400);

Android MediaPlayer is preparing too long

Hey,
I'm using MediaPlayer to play a regular ShoutCast stream. The code is straightforward with prepareAsync() and a handler to start the playback. While it works flawlessly with some streams like DI.FM or ETN.FM (http://u10.di.fm:80/di_progressive), with others (http://mp3.wpsu.org:8000/) it won't go past the prepare state. No other listeners are called either.
//Uri streamUri = Uri.parse("http://u10.di.fm:80/di_progressive"); /* works */
Uri streamUri = Uri.parse("http://mp3.wpsu.org:8000/"); /* stuck on prepare state */
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(this.getBaseContext(), streamUri);
mediaPlayer.prepareAsync();
Any feedback is appreciated!
I think that there are some compatibility problems with the server end.
This is rather strange since the emulator handles it ok in my case - just not on my Froyo Galaxy S, even though it is the same API version.
It could be a codec issue, http streaming issue, I do not know.
But all the servers that fail tend to be old ones, with "Copyright 1998 - 2004" at the bottom... Not exactly recent or up to date you would think.
One potential workaround (which I have not tried yet) would be to use the StreamProxy, which would also make your code compatible with 2.1 and possibly earlier versions too. At the cost of extra work, extra code, and without doubt extra bugs...
In case you are not aware of it, there is another player bug report for 2.2 which may be relevant too:
Basic streaming audio works in 2.1 but not in 2.2
I'm facing an issue when MP "hangs" at preparing state too long (stream) and i'm trying to stop it using reset(). This causes MP to hang and thus my whole app freezes. Seems like there is no way to stop MP at preparing state. Im thinking on use prepare() wrapped in thread instead of prepareAsync(). Then i'll be able to kill that thread. As for now i did it in following way:
private void actionCancel(){
try {
mp.setDataSource(new String());
} catch (Exception e) {
e.printStackTrace();
android.util.Log.d(TAG,"actionCancel(): mp.setDataSource() exception");
mp.reset();
}
}
and it works 4me.
Additionally i have a following counter:
#Override
public void onBufferingUpdate(final MediaPlayer mp, final int percent) {
if (!mp.isPlaying()){
// android.util.Log.d(TAG,"onBufferingUpdate(): onBufferingUpdateCount = "+onBufferingUpdateCount);
if (onBufferingUpdateCount>MAX_BUFFERING_UPDATES_AT_PREPARING_STATE)
restartMP();
onBufferingUpdateCount++;
return;
}
}
i'd discover this listener always triggers at preparing state. So if it triggers more than 10 times and MP is still not playing i'm just restarting it:
private void restartMP(){
if (mp!=null)
if (mpState==MediaPlayerState.Preparing)
actionCancel();
else
mp.reset();
else
mp = new MediaPlayer();
mpState = MediaPlayerState.Idle;
onBufferingUpdateCount=0;
//isRequestCancelled=false;
requestTrackInfoStartedAt=0;
requestPlay();
}
note MediaPlayerState is my custom enum which has "Preparing" value. Also mpState is a class property/field which holds current MediaPlayerState state. Before starting prepareAsync() im setting mpState to MediaPlayerState.Preparing after it completes im setting it to MediaPlayerState.Started or other corresponding value.

Categories

Resources