I am using this setOnClickListener() inside an one of the method in my Android App.Here I have used A mediaPlayer, which is declared locally.
Like this I also have two more methods which all uses mediaplayer. Also I have declared a global Mediaplayer & used it in various places of my onCreate().
public void setOnClickListenerWithMedia(ImageView iv,final int drawable,final int sound) {
iv.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
stopAllSoundsAndClearMemory();
switchCases();
iv_gone();
fullscreenImage.setVisibility(View.VISIBLE);
fullscreenImage.setImageResource(drawable);
MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(), sound);
mediaPlayer.start();
}
});
}
My problem is if I click on any other method, I have to stop the MediaPlayer. For Globally declared MediaPlayer Object(mp.). I can directly use,
if(mp!=null&&mp.isPlaying()){
mp.stop();
}
and I can stop it. But I also want to stop the sound from all the methods. How is it possible?
P.S: -> If I use mp in all the methods , it is not playing the sound & saying to create static mediaPlayer.
Thank you.
Every time when you are creating new player assign it to Global MediaPlayer instance.
i.e
declare mediaPlayer like this
MediaPlayer mp;
And then in your onClick or in other other methods use like this
And check whether MediaPlayer already exist or not
f(mp!=null&&mp.isPlaying()){
mp.stop();
mp.release();
}
mp=MediaPlayer.create(getApplicationContext(), sound);
mp.start();
try to design your mediaplayer as a singleton mode, and then your mediaplayer will be created only one instance object through the whole app.
Related
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.
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);
I have an android app with a button that plays a sound. the code for playing the sound:
if (mp != null)
{
mp.release();
}
mp = MediaPlayer.create(this, R.raw.match);
mp.start();
mp is a field in the activity:
public class Game extends Activity implements OnClickListener {
/** Called when the activity is first created. */
//variables:
MediaPlayer mp;
//...
The app runs ok, but after clicking the button about 200 times on the emulator, app crashed and gave me this error https://dl.dropbox.com/u/5488790/error.txt (couldn't figure how to post it here so it will appear decently)
i am assuming this is because the MediaPlayer object is consuming up too much memory, but isn't mp.release() supposed to take care of this? What am i doing wrong here?
If you are attaching a sound effect to a button, MediaPlayer in general is far too heavyweight for this operation. You're getting unnecessary latency each time just to load up the sound data into memory. You should look at using SoundPool instead.
In either case, there is no valid reason to release and re-create the MediaPlayer each time. If you decide to use MediaPlayer, control the single instance you have with the button clicks.
MediaPlayer mp;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Other init code
//Create the player this way so it doesn't auto-prepare
mp = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.match);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
}
public void onDestroy() {
super.onDestroy();
//Release it only when no longer needed
mp.release();
mp = null;
}
public void onButtonClick(View v) {
if (mp.isPlaying()) {
mp.stop();
}
//Play the sound
mp.prepare();
mp.start();
}
Hope that Helps, but again, I would highly recommend using SoundPool instead if this sound is just a short effect.
It looks like your code should work, but obviously release() isn't really releasing everything.
Maybe it's because you have to reload R.raw.match every time you want to play the sound. If R.raw.match is just a short sound effect, then you might want to consider using SoundPool instead.
If you use SoundPool you only have to load R.raw.match once which may prevent the memory issues.
This tutorial has a good example on how to use it: http://www.vogella.com/articles/AndroidMedia/article.html#tutorial_soundpool
You pretty much just make one instance of SoundPool then load the sound once and play it when you need it.
Hope this helps!
Edit
If you want to use MediaPlayer...
public class Blah extends Activity implements OnClickListener {
MediaPlayer mp;
#Override
public void onCreate(Bundle b)
{
// blah blah
mp = MediaPlayer.create(R.raw.match);
// blah blah
}
#Override
public void onClick(View v)
{
if (v.getId() == yourButtonID)
{
// play sound from beginning
mp.seekTo(0);
mp.start();
}
}
}
This way you only create one instance and whenever you want to play it, you just rewind it to the beginning then play.
Try
if (mp != null)
{
mp.release();
}
mp = MediaPlayer.create(this, R.raw.match);
mp.prepare(); // not needed
mp.start();
Good luck!!
if you hold the MediaPlayer, release it at the end of the activity
#Override
void onDestroy() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
super.onDestroy();
}
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 getting problems in playing audio(mp3) files this music files are like click sounds its residing at the raw folder, the problem is if there are many clicks at random intervals it throws an exception of nullPointer. It occurs anywhere when the click is done and anytime, is it related to the memory issue or MediaPlayer related problem, pls any suggestion will be appreceated.
Its simple media player object that i m calling, but its a games so on touch it plays the files, so in game i have many things to drag so i want a click sound at that time, sometime it works fine but when exceeds certain limit it throws null pointer exceptions. this is the code:
MediaPlayer mp= MediaPlayer.create(context,R.raw.soun1);
mp.start();
thats it:
just try this ::
MediaPlayer mp = new MediaPlayer();
mp= MediaPlayer.create(this,R.raw.soun1);
mp.start();
permission in manifest file:::
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
To play media player...we need two classes..
let us suppose mainactivity.java is our first file..
here we define two buttons - start_button & stop_button
mButton_start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent mIntent=new Intent(MainActivity.this,maservice.class);
startService(mIntent);
}
});
mButton_stop.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent mIntent=new Intent(MainActivity.this,maservice.class);
stopService(mIntent);
}
});
maservice.java is our another java file. Here we define media player and also there should be 3 methods: onCreate(), onStart(), onDestroy().
Here is the code:
MediaPlayer mPlayer;
#Override
public void onCreate()
{
super.onCreate();
mPlayer=MediaPlayer.create(this, R.raw.kyun);
mPlayer.setLooping(true);
}
#Override
public void onStart(Intent miIntent, int startid)
{
super.onStart(miIntent, startid);
mPlayer.start();
}
#Override
public void onDestroy()
{
super.onDestroy();
mPlayer.stop();
}
We also have to define these java files in manifest file
mainactivity.java is defined under activity tag
but maservice.java is defined under service tag
I got my answer, its SoundPool, especially created when the concern of game like application where the sound files are used continuously, so here we should use SoundPool except of MediaPlayer.
The issue is with the MP3 encoding. I tried with the same code, few work and few don't. So please try with a different one if it shows up the same error next time.