Media Player stops working after multiple use - android

Im using a MediaPlayer to play a sound every time a second goes off this is my code:
// Define CountDown Timer Attributes//
waitTimer1 = new CountDownTimer(60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
long timeLeft = millisUntilFinished / 1000;
Timer.setText("" + String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
if (timeLeft >= 43) {
mp = MediaPlayer.create(getApplicationContext(), R.raw.beeb1);
mp.start();
}
}
Once the timer hits 43 seconds the MediaPlayer stops like its supposed to.
after I call the MediaPlayer release() like so:
(The Button is pressed every single time so I know it is getting released
case R.id.Team1:
Category.team_one++;
number1.setText(String.valueOf(Category.team_one));
t1.setEnabled(false);
t2.setEnabled(false);
next.setEnabled(true);
Timer.setText("1:00");
mp.release();
break;
The problem is after two times of playing the same sound, it just completely stops playing it. Not sure why. The MediaPlayer will only play the sound the first time the timer starts. The second time it will get to 45 seconds then stop working. The third time and so on it wont make a sound at all. Please help, Thanks!
here is all the code:
// Declare TextView Variable Number One//
protected TextView number1;
// Declare TextView Variable Number Two//
protected TextView number2;
// Declare TextView Variable Timer//
protected TextView Timer;
// Declare TextView Variable Word//
protected TextView word;
// Declare Button Variable Next//
protected Button next;
// Declare CountDown Timer Variable//
private CountDownTimer waitTimer1;
// Declare Button Variable Team One//
protected Button t1;
// Declare Button Variable Team Two//
protected Button t2;
// Declare Media_Player Variable MP//
MediaPlayer mp;
// Where List Starts//
int stringListCounter;
// Shuffle List//
#Override
public void onResume() {
super.onResume();
stringListCounter = randInt(0, 100);
}
// Shuffle List
private int randInt(int min, int max) {
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
// What Happens When Activity Starts//
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animals);
// Link Button Team One to Activity_Animals//
t1 = (Button) findViewById(R.id.Team1);
t1.setEnabled(false);
t1.setOnClickListener(this);
// Link Button Number One to Activity_Animals//
number1 = (TextView) findViewById(R.id.Number1);
number1.setText(String.valueOf(Category.team_one));
// Link Button Number Two to Activity_Animals//
number2 = (TextView) findViewById(R.id.Number2);
number2.setText(String.valueOf(Category.team_two));
// Link Button Team Two to Activity_Animals//
t2 = (Button) findViewById(R.id.Team2);
t2.setEnabled(false);
t2.setOnClickListener(this);
// Link TextView Timer to Activity_Animals//
Timer = (TextView) findViewById(R.id.Timer);
// Link Button Next to Activity_Animals//
next = (Button) findViewById(R.id.Next);
next.setOnClickListener(this);
// Link TextView Word to Activity_Animals//
word = (TextView) findViewById(R.id.Word);
}
// What Happens When Said Variable Is Clicked//
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.Next:
t1.setEnabled(false);
t2.setEnabled(false);
next.setText("next");
if (waitTimer1 == null) {
// Define CountDown Timer Attributes//
waitTimer1 = new CountDownTimer(60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
long timeLeft = millisUntilFinished / 1000;
Timer.setText("" + String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
if (timeLeft >= 43) {
mp = MediaPlayer.create(getApplicationContext(), R.raw.beeb1);
mp.start();
}
}
#Override
public void onFinish() {
t1.setEnabled(true);
next.setEnabled(false);
waitTimer1 = null;
Timer.setText("0:00");
next.setText("Start");
}
}.start();
// Repeat Words//
if (word.getText().toString().equals("Big Foot")) {
stringListCounter = 0;
}
// Change To Next Word//
stringListCounter++;
word.setText(stringIdList[stringListCounter]);
} else{
// Repeat Words//
if (word.getText().toString().equals("Big Foot")) {
stringListCounter = 0;
}
// Change To Next Word//
stringListCounter++;
word.setText(stringIdList[stringListCounter]);
}
break;
case R.id.Team1:
Category.team_one++;
number1.setText(String.valueOf(Category.team_one));
t1.setEnabled(false);
t2.setEnabled(false);
next.setEnabled(true);
Timer.setText("1:00");
mp.stop();
mp.reset();
mp.release();
break;
case R.id.Team2:
Category.team_two++;
number2.setText(String.valueOf(Category.team_two));
t1.setEnabled(false);
t2.setEnabled(false);
next.setEnabled(true);
Timer.setText("1:00");
mp.release();
mp = null;
break;
}
}
}

The problem is in this code:
#Override
public void onTick(long millisUntilFinished) {
long timeLeft = millisUntilFinished / 1000;
Timer.setText("" + String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
if (timeLeft >= 43) {
mp = MediaPlayer.create(getApplicationContext(), R.raw.beeb1);
mp.start();
}
}
Right now, on every "tick" (1000 ms) it is creating a new MediaPlayer and starting it until the countdown is less than 43, which means you are starting 17 MediaPlayers - and not releasing any of them except the last one. So you are probably causing memory issues with MediaPlayer
Since you are using a repeated sound, you should simply create your MediaPlayer in onCreate and on each tick reset/replay it. You don't need to re-create/release/etc.

Related

Countdown timer that that increases speed after button press

I am trying to create a countdown timer that will increases its speed after a button press I uses the counter also to adjust a progress bar.
Right now I am adjusting the speed (increasing) after the button is pressed but it does not start from the beginning. For example, when I start my program the timer start from the beginning and decreases progressively, which is fine. However, when I press the button the counter does not start from the beginning like this:
I want just to make it run faster after each button press, not to decrease the length.
this is my code:
mTrueBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//is the user right? if pressing True button
if(isMathProblemTrue == 1){
//user is correct
Toast.makeText(MainActivity.this,"Correct!",Toast.LENGTH_SHORT).show();
generateMathProblem();
timer_length *= 0.8;
timer_interval *= 0.8;
Log.d(TAG,"time length:"+timer_length);
Log.d(TAG,"time interval:"+timer_interval);
mCountDownTimer.cancel();
createNStartTimer();
//restartTimer();
}else{
//user is incorrect
transferUserToStartScreen();
//reset the timer
mCountDownTimer.cancel(); // cancel
}
}
});
private void createNStartTimer() {
mCountDownTimer = new CountDownTimer(timer_length,timer_interval) {
#Override
public void onTick(long millisUntilFinished) {
Log.d(TAG,"Mil until finish:"+millisUntilFinished);
int progress = (int) (millisUntilFinished/100);
mProgressBar.setProgress(progress);
}
#Override
public void onFinish() {
mProgressBar.setProgress(0);
transferUserToStartScreen();
}
}.start();
}
create 2 global constants outside the functions
int totalMillisUntilFinished = 0;
bool firstTime = true;
we initialize the totalMillisUntilFinished when onTick is called for the time, so update your your onTick function:
private void createNStartTimer() {
firstTime = true;
mCountDownTimer = new CountDownTimer(timer_length,timer_interval) {
#Override
public void onTick(long millisUntilFinished) {
if(firstTime){totalMillisUntilFinished = millisUntilFinished; firstTime = false;}
Log.d(TAG,"Mil until finish:"+millisUntilFinished);
int progress = (int) (millisUntilFinished*100/totalMillisUntilFinished);
mProgressBar.setProgress(progress);
}
Personally, I use Handlers and Runnables, which I would definitely suggest looking into instead.

Build count down timer with pause button in android

I tried to build a contdown timer with pause button, for making timer to pause I tried to build a new timer with the left time, below is my code, but the problem is that it works just once, after pressing pause button for twice, old timer does not get cancel and wotks with the new one, what can I do?
pauseB.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!timerHasPaused) {
startTime = (long) (temp * 1000);
countDownTimer.cancel();
countDownTimer = new MyCountDownTimer(startTime, interval);
timerHasPaused = true;
pauseB.setText("Play");
} else {
PcountDownTimer.start();
timerHasStarted = false;
pauseB.setText("Pause");
}
}
});

How to wait application until countDownTimer finish

Similar query: wait until all threads finish their work in java
Hello,
I'm developing android application that contains some kind of count down timer. My problem is, that I have multiple count down timers, that sets text of TextView and have to work separately (first count down timer has to wait until the second one is finished etc.)
See code:
MyCountDownTimer.java
public class MyCountdownTimer extends CountDownTimer {
TextView tv;
// default constructor
public MyCountdownTimer (long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
// constructor
public MyCountdownTimer(int hours, int mins, int secs,
long countDownInterval, TextView tv) {
super(3600000 * hours + 60000 * mins + secs * 1000, countDownInterval);
this.tv = tv;
// all other settings
}
// when finished, set text of textview to done
#Override
public void onFinish() {
tv.setText("done!");
}
// when working periodically update text of text view to value of time left
#Override
public void onTick(long millisUntilFinished) {
tv.setText(/*function setting text of TextView based on time left*/);
}
}
Timer.java
public class Timer extends Fragment {
Button bStart;
Button bStop;
TextView tvShowTime;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.timer, container, false);
}
public void onStart() {
super.onStart();
bStart = (Button) getView().findViewById(R.id.bTimerStart);
bStop = (Button) getView().findViewById(R.id.bTimerStop);
tvShowTime = (TextView) getView().findViewById(R.id.showTime);
// setting on button start click
bStart.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
timerStart();
}
});
// setting on button stop click
bStop.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
timerStop();
}
});
}
private void timerStart() {
bStart.setClickable(false);
int repeat = 2;
int hour, mins, secs;
for (int i = 0; i < 2 * repeat; i++) {
if (i % 2 == 0) {
// setting working count down timer values
mins = 1;
} else {
// setting resting count down timer values
secs = 30;
}
timerCount = new MyCountdownTimer(hours, mins, secs, REFRESH_RATE,
tvShowTime);
timerCount.start();
//////////////////////////////////////////////////
// HERE I WANT TO WAIT UNTIL COUNTDOWN IS DONE //
// ATM SECOND, THIRD AND FOURTH COUNT DOWN //
// TIMER IS STARTED //
//////////////////////////////////////////////////
}
}
-- EDIT --
At the end I did 2 CountDownTimers where first one calls in onFinish() second one and second one calls the first one until repeat = 0;
In final it was the best sotution for me. Anyway thanks for help, #Triode's answer helped me a lot
Start your SECOND, THIRD AND FOURTH COUNT DOWN TIMER in onFinish() of Your MyCountdownTimer
I think you have to put down the timerStop() method implementation and do not try to hide it,you need answer but you don't want others to benifit :s

Countdown Timer keeps starting over on button press

Okay, so I have a countdown timer, and my app requires the user to tap a button numerous times, however the timer starts ON that button tap. My problem is:
I have a 10 second countdown timer that starts at the press of the button, but instead of just continuing down to 0, it restarts at 10 everytime the user taps the button. How do I make it so when the user taps it the first time, it keeps counting down?
My code:
private Button tapBtn;
TextView cm;
tapBtn = (Button) findViewById(R.id.Tap);
cm = (TextView) findViewById(R.id.Timer);
final CountDownTimer aCounter = new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
cm.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
cm.setText("Time's Up!");
}
};
aCounter.cancel();
tapBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
scr = scr - 1;
TextView Score = (TextView) findViewById(R.id.Score);
Score.setText(String.valueOf(scr));
aCounter.start();
}
});
}
Are you trying to make it so that if the user has already started the timer, subsequent button presses don't restart it from the first tap? If so, all you should have to do is put an if statement in your onclick that checks to see if the timer is still counting down, i.e. check and see if the current time is greater than 0 on the counter.
Edit: here's code
final CountDownTimer aCounter = new CountDownTimer(10000, 1000) {
private long timeLeft;
public long getTimeLeft() {
return timeLeft;
}
public void onTick(long millisUntilFinished) {
timeLeft = millisUntilFinished / 1000;
cm.setText("Time Left: " + timeLeft);
}
public void onFinish() {
cm.setText("Time's Up!");
}
};
aCounter.cancel();
tapBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (aCounter.getTimeLeft() == 0) {
scr = scr - 1;
TextView Score = (TextView) findViewById(R.id.Score);
Score.setText(String.valueOf(scr));
aCounter.start();
}
}
});
}
one way to do it is to create a flag that gets set on the first tap and have the onclick event flip the flag on the first click, and put the timer start inside of an if statement that only occurs if the flag hasn't been set.

How to set up a countup timer only when the button press?

I am implementing a countup timer and I follow an example from StackoverFlow.
In my version, I will press the Begin button to start counting and the Stop button to stop.
But the problem is that the counting start immediately after i enter the activity.
Any idea how to make it the way i want?
public class StartActivity extends Activity
{
Button beginRecordingButton;
TextView timer;
long startTime;
long countup;
#Override
protected void onCreate(Bundle savedInstanceState)
{super.onCreate(savedInstanceState);
setContentView(R.layout.startactivity);
beginRecordingButton = (Button) findViewById(R.id.BeginRecording);
timer = (TextView) findViewById(R.id.timer);
final Chronometer stopwatch = (Chronometer) findViewById(R.id.chrono);
startTime = SystemClock.elapsedRealtime();
stopwatch.setOnChronometerTickListener(listener);
beginRecordingButton.setOnClickListener(new OnClickListener()
{
int counter = 0;
public void onClick(View v)
{
if (counter % 2 == 0)
{
stopwatch.start();
beginRecordingButton.setText("Stop");
}
if (counter % 2 == 1)
{
stopwatch.stop();
beginRecordingButton.setText("Begin");
}
counter++; //counter is used for knowing it is stop or begin
}
});
}
private OnChronometerTickListener listener = new OnChronometerTickListener()
{
public void onChronometerTick(Chronometer chronometer)
{
String text;
countup = (SystemClock.elapsedRealtime() - chronometer.getBase())/1000;
if(countup%60<10)
{
text = (countup/60) + ":0" + (countup%60);
}
else
{
text = (countup/60) + ":" + (countup%60);
}
timer.setText(text);
}
};
}
I found the solution by doing follow:
long test;
test = (SystemClock.elapsedRealtime() - stopwatch.getBase())/1000;
Log.i(TAG, = (SystemClock.elapsedRealtime() - chronometer.getBase()) / 1000 - test;
basically String.valueOf(test));
stopwatch.start();
countup the idea is to subtract the passing time if i press the start button so it goes from 0

Categories

Resources