Multiple sound in Media Player application crashed - android

I have developed app in which there are 4 sound files playing together
First sound :
on next button press
-Second sound :
on previous button press
Third sound :
plays sound of item
Fourth sound :
plays on item (How item speaks)
Everything works well until user play back and fourth quickly, text-to-speech engine crash with
MediaPlayer: error (-19, 0) android
i tried to reset media player , release and stop in next and previous button, but still sound of items stops after few back and fourth.
What i have done :
public class A extends Activity {
int imgArr[] = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d};
int soundsrc[] = {R.raw.a, R.raw.b, R.raw.c, R.raw.d};
String pro[] = new String[]{"a", "b", "c", "d"};
ImageView iView;
int count = 0;
TextToSpeech txtToSpeech1;
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_names);
stopService(new Intent(this, PlayMusic.class));
iView = (ImageView) findViewById(R.id.imageView5);
iView.setImageResource(R.drawable.befora);
txtToSpeech1 = new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() {
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
txtToSpeech1.setLanguage(Locale.UK);
txtToSpeech1.speak(pro[count], TextToSpeech.QUEUE_FLUSH, null);
}
}
});
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
aSounds();
}
}, 1000);
}
#Override
public void onDestroy() {
// Don't forget to shutdown!
if (txtToSpeech1 != null) {
txtToSpeech1.stop();
txtToSpeech1.shutdown();
}
super.onDestroy();
}
public void onPause(){
if(txtToSpeech1 !=null){
txtToSpeech1.stop();
txtToSpeech1.shutdown();
}
super.onPause();
}
public void aSounds() {
mp = MediaPlayer.create(ANames.this, soundsrc[count]);
mp.start();
}
public void forwardd(View v) {
buttonSounds(R.raw.multimedia_button_click);
if (count < imgArr.length && count >= 0) {
count++;
if (count == imgArr.length)
count = 0;
iView.setImageResource(imgArr[count]);
if (txtToSpeech1.isSpeaking()) {
Log.i("Tag", "Stop speaking");
txtToSpeech1.stop();
}
txtToSpeech1.speak(pro[count], TextToSpeech.QUEUE_FLUSH, null);
// Execute some code after 2 seconds have passed
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
aSounds();
}
}, 1000);
}
}
public void backwardd(View v) {
buttonSounds(R.raw.multimedia_button_click);
if (count >= 0 && count < imgArr.length) {
count--;
if (count == -1) {
count = imgArr.length - 1;
}
iView.setImageResource(imgArr[count]);
txtToSpeech1.speak(pro[count], TextToSpeech.QUEUE_FLUSH, null);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
aSounds();
}
}, 1000);
}
}
public void onImageClick(View v) {
txtToSpeech1.speak(pro[count], TextToSpeech.QUEUE_FLUSH, null);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
aSounds();
}
}, 1000);
}
public void home(View v) {
buttonSounds(R.raw.multimedia_button_click);
Intent ii = new Intent(ANames.this, PlayMusic.class);
finish();
startService(ii);
}
public void buttonSounds(int src) {
mp = MediaPlayer.create(ANames.this, R.raw.multimedia_button_click);
mp.start();
}
}
-- i have been trying since very very very long
-- tried almost all stack-overflow answers also Google regarding media player working .
-- also how to stop , release , reset, start media player on button click, but nothing works for me..
-- So at last decided to put question in stack-overflow for help
-- any help is heartly welcome and thanks in advance

If the buttons plays a sound effect like 1-4 seconds. Consider using SoundPool class. It should be used for that stuff as I know. Media player errors LINK and LINK. It seems whoever were getting error 19 needed to release the resource which he was playing.

Related

stop mediaplayer sound when press back button in android studio!pls help me to find my mistake.thanks alot

in my app exist two activity and a button . when user touch button in activity1 , app go to activity2 that three image with sound played Consecutively and repeat until user touch back button.
when user touch back button application go to activity1 .
The problem is that when the back button is pressed, it goes to the second activity, but there is no image displayed, and the broadcast sound is not interrupted, and it is constantly repeated, and the program loop does not come out.
I do not know where the program logic is wrong!
please guide me
my code is:
{
public MediaPlayer mp = new MediaPlayer();
Button button;
ImageView im;
Context context;
int current_img = 0;
int current_aud = 0;
boolean flag= false;
int[] sounds={R.raw.anar,R.raw.ab,R.raw.abi};
int[] images = { R.drawable.anar, R.drawable.water , R.drawable.abi};
String[] texts={"انار","آب","آبی"};
AnimationDrawable animation = new AnimationDrawable();
#Override
public void onBackPressed() {
if (mp != null && mp.isPlaying()) {
Toast.makeText(MainActivity.this, "in backpress", Toast.LENGTH_LONG).show();
mp.stop();
mp.release();
mp = null;
super.onBackPressed();
this.finish();
}
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView=findViewById(R.id.textView);
im = findViewById(R.id.imageView);
im.setImageResource(R.drawable.anar);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int i = 0;
int j = 0;
public void run()
{
textView.setText(texts[i]);
im.setImageResource(images[i]);
i++;
mp = MediaPlayer.create(MainActivity.this, sounds[j]);
Toast.makeText(MainActivity.this, "in while", Toast.LENGTH_LONG).show();
mp.start();
j++;
if (j > sounds.length - 1) {
j = 0;
}
if (i > images.length - 1) {
i = 0;
}
handler.postDelayed(this, 5000); //for interval...
}
};
}
}
move the handler to class , and release it in onBackPressed()
try to change the onBackPressed():
final Handler handler = new Handler();
#Override
public void onBackPressed() {
Toast.makeText(this, "in backpress", Toast.LENGTH_LONG).show();
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
if(handler!=null){
handler.removeCallbacksAndMessages(null);
}
super.onBackPressed();
}

Seekbar is still not updating

I made these two method to update seekbar every 100ms:
public void updateSeekBar() {
handler.postDelayed(mUpdateTimeTask, 100);
}
private Runnable mUpdateTimeTask = new Runnable() {
#Override
public void run() {
mySeekBar.setMax(mySong.getDuration());
x = mySong.getCurrentPosition();
mySeekBar.setProgress(x);
handler.postDelayed(this, 100);
}
};
and put it inside my playMusic method:
public void playMusic() {
//just a test from intent.getExtra
if(test.equalsIgnoreCase("Jason Mraz")) {
mySong = MediaPlayer.create(MusicClass.this, jm[musicCounter]);
displaySong(jm);
songNumbers = jm.length;
}else if(test.equalsIgnoreCase("fob")) {
mySong = MediaPlayer.create(MusicClass.this, fob[musicCounter]);
displaySong(fob);
songNumbers = fob.length;
}else if(test.equalsIgnoreCase("ed")) {
mySong = MediaPlayer.create(MusicClass.this, ed[musicCounter]);
displaySong(ed);
songNumbers = ed.length;
}
//when the song is completed
mySong.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
nextSong();
}
});
//seekbar update
mySeekBar.setMax(mySong.getDuration());
mySeekBar.setProgress(0);
mySong.start();
updateSeekBar();
}
this is my onCreate method:
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.music);
artistName = (TextView)findViewById(R.id.artistName);
song = (TextView)findViewById(R.id.song);
musicCounter = 0;
ifPlaying = true;
isRandom = false;
random = (ImageButton) findViewById(R.id.random);
stop = (ImageButton)findViewById(R.id.stop);
myImageView = (ImageView)findViewById(R.id.myImageView);
dice = new Random();
mySeekBar = (SeekBar)findViewById(R.id.mySeekBar);
test = getIntent().getStringExtra("test");
if(test.equalsIgnoreCase("Jason Mraz")) {
artistName.setText("Jason Mraz");
displayPP();
songNumbers = jm.length;
myImageView.setImageResource(R.drawable.jason_mraz);
} else if (test.equalsIgnoreCase("fob")) {
artistName.setText("Fall Out Boys");
displayPP();
songNumbers = fob.length;
myImageView.setImageResource(R.drawable.fall_out_boys);
} else if (test.equalsIgnoreCase("ed")) {
artistName.setText("Ed Sheeran");
displayPP();
songNumbers = ed.length;
myImageView.setImageResource(R.drawable.ed_sheeran);
}
playMusic();
mySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (b) {
mySong.seekTo(i);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
mySong.pause();
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (ifPlaying == true) {
mySong.start();
} else {
return;
}
}
});
}
My application says Unfortunately stopped. But when I remove the updateSeekbar in playMusic method it works fine, but without the updating seekBar every second. The setOnSeekBarChangeListener works perfectly fine, the only problem is I can't make updateSeekBar method work because it is alwats stopping my application and force exit.
The symptoms you are describing is called an ANR. It means that you is doing to much work in the main thread.
What you need todo is review what you are triggering in your mUpdateTimeTask.
Next make sure your handler is running on the UI since your are updating views:
Handler handler = new Handler(Looper.getMainLooper());

Android Pause and Resume Background Activity

In one activity of my app, there are an imagview and a textview that are changing every 3 seconds.
I first set this up with a handler and thread runnable. It works fine, but when I use removeCallbacks with the pause button, it will not pause in the middle of the Thread. It completes the Thread runnable before pausing. I need it to pause when the button is clicked no matter where it is in the runnable.
I thought about using an asynctask but I'm not sure how this would work.
I know there has to be a way to do this, as you can pause almost any game you download. Does anyone have any suggestions on the best/easiest way to do this?
Thanks so much!! :)
public class Workout extends AppCompatActivity {
private String[] messages = {"1", "2", "3", "4", "5"};
final Handler handler = new Handler();
private int nextIndex;
String mDrawableName[] = {"bodypart70", "equipment70", "settings70", "time70", "bodypart70"};
private int nextImage;
ImageView image;
private ProgressBar progressBar;
private int progressStatus = 0;
Runnable r = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.workout);
image = (ImageView) findViewById(R.id.exerciseImage);
final TextView text = (TextView)findViewById(R.id.textView4);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
//changing
r = new Runnable(){
#Override
public void run(){
if (messages.length > nextIndex) {
//change textview
text.setText(messages[nextIndex++]);
//change image
int resID = getResources().getIdentifier(mDrawableName[nextImage++] , "drawable", getPackageName());
image.setImageResource(resID);
//restart progress bar
progressStatus = 0;
progress();
//do it after 3 seconds
handler.postDelayed(this, 3000);
}
}
};
handler.postDelayed(r, 0);
}
public void progress(){
new Thread(new Runnable() {
public void run() {
long timerEnd = System.currentTimeMillis() + 3 * 1000;
while (timerEnd > System.currentTimeMillis()) {
progressStatus = 3 - (int) (timerEnd - System.currentTimeMillis()) / 1000;
// Update the progress bar
handler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressStatus);
}
});
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Log.w("App", "Progress thread cannot sleep");
}
}
}
}).start();
}
public void pauseWorkout(View view){
handler.removeCallbacks(r);
}
public void resumeWorkout(View view){
handler.postDelayed(r, 0);
}
}
It looks like the while-loop in your progress() function is still working after you press your pause button.
Try the following: Create a global boolean that indicates you're in a paused or resuming state. Put it at the top of your code:
boolean resume = true;
Update your while condition in progress()
while (resume && timerEnd > System.currentTimeMillis()) {
Update your workout functions:
public void pauseWorkout(View view){
handler.removeCallbacks(r);
resume = false;
}
public void resumeWorkout(View view){
handler.postDelayed(r, 0);
resume = true;
}

How to loop a sound a different number of times at set intervals - android

I've done a little with android in the past, but this is the first time I've touched it in over a year and I've been stuck on this problem since yesterday.
I'm working on a project with someone and I need to play a sound a certain number of times at set intervals. (For example, play once after one minute, twice after two minutes, three times after three minutes, and on and on). I can get the sound to play at whatever interval, that's not an issue, but I can't figure out how to get it to play the correct number of times at each interval. It either ends up looping infinitely, playing once each time the interval is up or playing once and stopping.
Tried TimerTask, switched to Handler/Runnable, tried using a for loop and using an if statement with counter. After two evenings of multiple attempts, hours of research and my limited experience, this is the one problem I've run into that I haven't been able to figure out.
Here's the code I've currently got in for this particular feature. I'm having issues with the Runnable tenMinChime and OnCompletionListener chimeCompletion. Any guidance at all is very appreciated.
public class MainActivity extends AppCompatActivity {
TextView chimeOn, chimeOff;
Handler chimeHandler = new Handler();
MediaPlayer.OnCompletionListener chimeCompletion;
MediaPlayer cp;
int chimeCount = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (screen == 1) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
setContentView(R.layout.activity_main);
chimeOn = (TextView) findViewById(R.id.chimeOn);
chimeOff = (TextView) findViewById(R.id.chimeOff);
chimeOn.setTextColor(0xFFbebebe);
chimeOff.setTextColor(0xFF000000);
cp = MediaPlayer.create(this, R.raw.placeholder_chime);
chimeOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (chime == 0) {
chimeOn.setTextColor(0xFF000000);
chimeOff.setTextColor(0xFFbebebe);
handler2.postDelayed(tenMinChime, 5000);
chime = 1;
}
}
});
chimeOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (chime == 1) {
chimeOff.setTextColor(0xFF000000);
chimeOn.setTextColor(0xFFbebebe);
handler2.removeCallbacks(tenMinChime);
chime = 0;
}
}
});
chimeCompletion = new MediaPlayer.OnCompletionListener() {
int count = 0;
int maxCount = chimeCount;
#Override
public void onCompletion(MediaPlayer mp) {
if(count < maxCount) {
count++;
cp.seekTo(0);
cp.start();
cp.setOnCompletionListener(chimeCompletion);
}
}
};
public Runnable tenMinChime = new Runnable() {
public void run() {
chimeCount+=1;
cp.start();
cp.setOnCompletionListener(chimeCompletion);
}
};
Maybe this solves your issue ?
public class MainActivity extends AppCompatActivity {
TextView chimeOn, chimeOff;
Handler handler2 = new Handler();
MediaPlayer.OnCompletionListener chimeCompletion;
MediaPlayer cp;
int chimeCount = 0;
int mPlayCount=0;
int mMaxPlayCount=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (screen == 1) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
setContentView(R.layout.activity_main);
chimeOn = (TextView) findViewById(R.id.chimeOn);
chimeOff = (TextView) findViewById(R.id.chimeOff);
chimeOn.setTextColor(0xFFbebebe);
chimeOff.setTextColor(0xFF000000);
cp = MediaPlayer.create(this, R.raw.placeholder_chime);
chimeOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (chime == 0) {
chimeOn.setTextColor(0xFF000000);
chimeOff.setTextColor(0xFFbebebe);
handler2.postDelayed(tenMinChime, 5000);
chime = 1;
}
}
});
chimeOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (chime == 1) {
chimeOff.setTextColor(0xFF000000);
chimeOn.setTextColor(0xFFbebebe);
handler2.removeCallbacks(tenMinChime);
cp.setOnCompletionListener(null);
chime = 0;
mMaxPlayCount=0;
mPlayCount=0;
}
}
});
chimeCompletion = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if(mPlayCount < mMaxPlayCount) {
mPlayCount++;
cp.seekTo(0);
cp.start();
}
}
};
public Runnable tenMinChime = new Runnable() {
public void run() {
mPlayCount=0;
mMaxPlayCount= 3;
cp.setOnCompletionListener(chimeCompletion);
cp.start();
}
};

Issue with looping an audio file

How can i get the value of repetitions completed from mp.setLooping(true). I can use OnCompletionListener to get number of repetitions, but it produces 1sec delay between looping, which is annoying in a music oriented app. OnCompletionListener looping is not smooth asmp.setLooping(true).
Any suggestions ? Thank in advance.
Code with 1sec delay or gap between looping:
public class MainActivity extends Activity {
MediaPlayer mp1;
Button play;
int maxCount=10,n=1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play = (Button) findViewById(R.id.button1);
mp = MediaPlayer.create(MainActivity.this, R.raw.soundfile);
play.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mpplay();
}
});
}
private void mpplay() {
mp1.start();
mp1.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp1) {
if (n <= maxCount) {
mp1.start();
n++;
if (n >= maxCount) {
n = 1;
mp1.stop();
}
}
}
});
}}
Try this out:
MediaPlayer mp1;
double play_times = 10;
int sound_length;
Handler handler;
boolean sound_playing = false;
int times_played = 0;
public void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.home);
handler = new Handler();
mp1 = MediaPlayer.create(this, R.raw.soundfile);
sound_length = mp1.getDuration();
mpplay();
}
private void mpplay() {
times_played = 0;
mp1.setLooping(true);
mp1.start();
sound_playing = true;
handler.postDelayed(loop_stopper, (int)(sound_length*(play_times-.5)));
handler.postDelayed(counter, sound_length);
}
private Runnable loop_stopper = new Runnable() {
public void run() {
sound_playing = false;
mp1.setLooping(false);
}
};
private Runnable counter = new Runnable() {
public void run() {
if (sound_playing) {
times_played++;
handler.postDelayed(counter, sound_length);
}
}
};
handler.postDelayed(loop_stopper, (int)(sound_length*(play_times-.5)));
This line will stop the looping halfway through the last desired loop. Since this just means it won't continue looping, the sound file will still be fully played on the last repeat.

Categories

Resources