This code is called everytime I click a button. After some time when I click the button, the sound is not displayed anymore. I tried to use another music file, and also I tried to use the MediaPlayer instead of SoundPool, but the problem kept happening.
To be more specific about the problem, it is like: I click for 10 times and it is returning the sound, when I click once again it stops
public void displaySound(Context context){
SoundPool sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
int soundId = sp.load(context, R.raw.bubble_nice, 1);
sp.play(soundId, 1, 1, 0, 0, 1);
MediaPlayer mPlayer = MediaPlayer.create(context, R.raw.bubble_nice);
mPlayer.start();
}
When the sound stops, this is appearing in the log: E/MediaPlayer: error (1, -19)
I have tried your code and found a solution, you can try as follow:
first declare a mediaplayer object gloabally like
MediaPlayer mPlayer;
then use following method on click of button.
public void displaySound(Context context) {
if (mPlayer != null && mPlayer.isPlaying()) {
mPlayer.stop();
mPlayer.reset();
}
mPlayer = MediaPlayer.create(context, R.raw.bubble_nice);
mPlayer.start();
}
when activity pause you must to pause your Mediaplayer, and activity's onStart() metod you ca call it again. bellow code
#Override
protected void onStart() {
mPlayer.reset();
super.onStart();
}
#Override
protected void onPause() {
mPlayer.pause();
super.onPause();
}
#Override
protected void onDestroy() {
mPlayer.stop();
super.onDestroy();
}
It worked better for me with a small modification to BSavaliya's code:
First declare mPlayer as a global variable.
if (mPlayer != null )
{
if(mPlayer .isPlaying())
{
mPlayer .stop();
}
mPlayer .reset();
}
Related
My APP has 3 activities named "MainActivity", "LevelActivity" and "GameActivity". Now I want to play BGM in MainActivity and LevelActivity. When I jump from Main to Level, I don't want the music to start from the beginning. So I use Service to play BGM.
But the problem is that if I don't override onStop() in MainActivity, the BGM is still playing after I clicked the "HOME" button. But if I override onStop() in MainActivity, the BGM will stop when I jump from Main to Level.
public class MusicService extends Service {
private MediaPlayer mediaPlayer;
#Override
public void onCreate() {
// my codes...
}
#Override
public void onStart(Intent intent, int startId) {
// my codes...
}
#Override
public void onDestroy() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
What should I do to stop BGM when I press "HOME"?
Thanks.
you can do a trick by adding a boolean variable .
1- create a boolean variable isAppStillRunning = false
2- then when you want to start level activity make isAppStillRunning = true before startActivity()
3- whenever you go back to MainActivity make isAppStillRunning = false
now in onStop() in your MainActivity ,
if(!isAppStillRunning){
//do the proccess to stop music
}
I'm trying to make app like soundboard. Now I have small problem with playing the same sound after reset after playing 1st time.
final MediaPlayer SoundOne = MediaPlayer.create(this, R.raw.somesound);
final Button play_SoundOne = (Button) this.findViewById(R.id.play_SoundOne);
play_SoundOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SoundOne.start();
}
});
SoundOne.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
SoundOne.reset();
}
});
Can I get help how can I prepare that sound to play again after reset (I do reset to make space in memory for next sounds) but SoundOne.prepare() doesn't work if I put that before .start(). Any advice?
Based on the documentation:
It is a programming error to invoke methods such as getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioAttributes(AudioAttributes), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(long, int), prepare() or prepareAsync() in the Idle state for both cases. If any of these methods is called right after a MediaPlayer object is constructed, the user supplied callback method OnErrorListener.onError() won't be called by the internal player engine and the object state remains unchanged; but if these methods are called right after reset(), the user supplied callback method OnErrorListener.onError() will be invoked by the internal player engine and the object will be transfered to the Error state.
You cannot immediately start() or prepare after reset(). Based on the documentation for reset:
Resets the MediaPlayer to its uninitialized state. After calling this method, you will have to initialize it again by setting the data source and calling prepare().
The solution would be
Initialize the MediaPlayer again -> set the Data Source -> call prepare.
Alternatively you can avoid performing reset onCompletion. Instead, release the MediaPlayer onStop()
You can update your as follows:
MediaPlayer soundOne = null;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
....
play_SoundOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
soundOne.start();
}
});
}
#Override
protected void onStart() {
super.onStart();
if(soundOne == null){
soundOne = MediaPlayer.create(this, R.raw.somesound);
soundOne.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//Don't reset
}
});
}
}
#Override
protected void onStop() {
super.onStop();
soundOne.release();
soundOne = null;
}
The code I have so far is:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void SoundPlayer(View view) {
MediaPlayer soundMediaPlayer1 = MediaPlayer.create(this, R.raw.gun_sound);
soundMediaPlayer1.start();
}
public void DogSound(View view) {
MediaPlayer soundMediaPlayer2 = MediaPlayer.create(this, R.raw.cat_sound);
soundMediaPlayer2.start();
}
public void NewSound(View view) {
MediaPlayer soundMediaPlayer3 = MediaPlayer.create(this, R.raw.new_sound);
soundMediaPlayer3.start();
}
public void LaughTrack(View view) {
MediaPlayer soundMediaPlayer12 = MediaPlayer.create(this, R.raw.laugh_sound);
soundMediaPlayer12.start();
}
public void HorseSound(View view) {
MediaPlayer soundMediaPlayer4 = MediaPlayer.create(this, R.raw.horse_sound);
soundMediaPlayer4.start();
}
public void HeySound(View view) {
MediaPlayer soundMediaPlayer5 = MediaPlayer.create(this, R.raw.hey_sound);
soundMediaPlayer5.start();
}
private void Stop() {
startActivity(new Intent(this, MainActivity.class));
}
public void stop(View view) {
Stop();
}
}
The problem I face is that all the sounds overlaps and plays. I have a STOP button set up, but have no idea has to how to make it stops the media. Any feedback is helpful.
Thank you.
First of all, I would use only one Instance of the MediaPlayer. You can then use mediaPlayer.stop() to stop a sound and prepare the next one.
See the state diagram on https://developer.android.com/reference/android/media/MediaPlayer.html
1) Make the object of MediaPlayer in onCreate method don't create in every new method.
2) Before playing the music in another method first use stop() function to stop current playing sound(like mediaPlayer.stop(); ) then play the sound by start().
I have a media player as global variable and i wanna resume it in onResume and pause it in onPause but both give me nullpointerException. I don't know why it's giving media player as null. I don't thin we need log coz i know the error is nullpointerexception and on the line below mentioned.Here is my code
MediaPlayer md;
int position;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_slide_show);
md = new MediaPlayer();
md.setAudioStreamType(AudioManager.STREAM_MUSIC);
md = MediaPlayer.create(this, R.raw.tone);
md.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
md.start();
}
});
#Override
public void onPause(){
if(md != null ){
md.pause();
position = md.getCurrentPosition();
}
super.onPause();
}
#Override
public void onResume(){
super.onResume();
if(md != null){
md.start(); NullPointerException here
md.seekTo(position);
}
}
#Override
public void onStop(){
if(md != null){
md.stop(); NullPointerException here
md.release();
md = null;}
super.onStop();
}
I think you have misunderstood the android app cycle..when ever you press the home button to come out of the app, onStop() is being called along with onPause().
Because of this reason the MediaPlayer gets released every time, so you are receiving that null pointer Exception.
I believe, that you want to stop the music when the app is closed completely, then replace the onStop() with onDestroy()...that is the only problem related to null pointer Exception..
In the mainactivity I have create a handler as instance variable:
SeekBar seek_bar;
MediaPlayer player;
Handler seekHandler = new Handler();
Then I have the following two methods in the MainActivity to update the seekbar as the audio plays in media player:
public void getInit() {
seek_bar = (SeekBar) findViewById(R.id.seek_bar);
}
Runnable run = new Runnable() {
#Override
public void run() {
seekUpdation(); **//Exception comes here while closing the app**
}
};
public void seekUpdation() {
seek_bar.setProgress(mMediaPlayer.getCurrentPosition());
seekHandler.postDelayed(run, 1000);
}
The problem I am facing is that when the audio is running and user closes the application using device back buttton. I get NullPointerException. The destroy method of activity is:
#Override
protected void onDestroy() {
super.onDestroy();
if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
Remove any queued messages/callbacks from the handler in your onDestroy. My bet is that its running the last message after onDestroy is called.