I have a countdown timer which runs as soon as the generate expression button is clicked. Inside the timer I have made it work so when the timer runs it automatically clicks the button , so that the next expression is displayed. When the button is clicked 10 times it should start a new activity. But the problem I'm having is when the new activity has started it keeps starting the same activity. So i wanted the timer to stop as soon as the button has been clicked 10 times. I have tried countDownTimer.cancel(); to stop the timer as soon as 10 clicks have been clicked, but it doesn't seem to work.
Here is where the timer code is add:
public void generate_Clicked(View v){ // When Generate button is clicked
if(gencount <10){
if (!timerHasStarted) {
countDownTimer.start();
timeText.setText(timeText.getText() + String.valueOf(startTime/1000));
timerHasStarted = true;
}
else {
countDownTimer.cancel();
timerHasStarted = false;
}
// Fetch your random question
String Rquestion = multiArray[ar.get(gencount)][0];
displayExpression.setText(Rquestion);
displayAnswer.setText("");
setAnswer.setText("?");
setHints.setText("");
count =0;
gencount++;
}else{
// countDownTimer.cancel(); //This doesn't seem to work
Intent i = new Intent(getApplicationContext(),Score.class);
startActivity(i);
ar.clear();
}
} //End of generate_Clicked.
Heres the timer code:
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
timeText.setText("Time's up!");
Button buttonGenerate = (Button) findViewById(R.id.random_gen);
buttonGenerate.performClick();
countDownTimer.cancel();
countDownTimer.start();
}
#Override
public void onTick(long millisUntilFinished) {
timeText.setText("" + millisUntilFinished/1000);
}
}
There seems to be a bug in the CountDownTimer code, that prevents it from stopping. The cancel method does not work.
If you google you will see plenty of people describing the same problem.
So if you only start the activity when the counter is exactly 10.
if (gencount==10) {
// countDownTimer.cancel(); //This doesn't seem to work
Intent i = new Intent(getApplicationContext(),Score.class);
startActivity(i);
ar.clear();
}
instead of } else { it should work. and reset gencount when the button is clicked, and also you need to have a different way of executing the whole handling code.
Related
I'm creating a quiz app in android. I have written OnClickListener for next button to load next question. now I want to add timer to each question so that when timer ends it will automatically call OnClickListener of next button. How to implement this?
If you want to delay some code from running for a certain amount of time use a Runnable and a Handler like this
Runnable r = new Runnable() {
#Override
public void run(){
doSomething(); //<-- put your code in here.
}
};
Handler h = new Handler();
h.postDelayed(r, 1000);
You just need to call performClick() on an instance of your next button. Something like this:
nextButton.performClick()
That will execute everything you have inside of OnClickListener that is set for that button.
EDIT:
If I misunderstood your question and you are searching for Timer implementation, I recommend for you check CountDownTimer that is provided by Android team. You can check documentation with an example for his here:
https://developer.android.com/reference/android/os/CountDownTimer
You can have a method you call when the user clicks the next button say it's named as nextQuestion()
then add the listener of your next button
Button nextBtn = findViewById(..);
nextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
nextQuestion();
}
});
And the time would be CountDownTimer of say 1 min duration (60*1000 msec) and 1 second tick (1000 msec)
new CountDownTimer(60000, 1000) { // 1 min duration (60*1000 msec) and 1 second tick (1000 msec)
#Override
public void onTick(long millisUntilFinished) {
// do something each second
}
#Override
public void onFinish() {
// timer expired
nextQuestion();
}
}.start();
I want to make an application about mini game.
Detail : In 2 seconds you must to answer a question if you don't answer or the answer is wrong -> Game Over . But if your answer is true the Timer will reset become 0 and countdown again with diffirent question.
I have already seen many code about timer in website but I don't understand clearly about it :(
So I want to ask : How can i set up a timer run only 2 seconds and how can i reset it and continue with a new question ?
Please help me.
you can use CountDownTimer in android like this:
public class Myclass {
myTimer timer =new myTimer(2000,1000);
public void creatQuestion(){
timer.start();
//method you init question and show it to user
}
public void getUserAnswer(/*evry thing you expected*/)
{
//if answer is true call timer.start()
//else call timer.onFinish(); to run onfinish in timer
}
public class myTimer extends CountDownTimer {
public myTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
// you can update ui here
}
#Override
public void onFinish() {
this.cancel();
//fire game over event
}
}
}
i hope it make you satisfy
I've done something similar using Thread/Runnable.
Thread t = new Thread(new Runnable() {
public void run() {
final long startTime = getTime();
final long maxEndTime = startTime + 2000L;
try {
while (shouldContinueWaiting()) {
if (getTime() > maxEndTime) {
throw new TimeoutException();
}
sleep();
}
} catch (InterruptedException e) {
handleInterrupt();
} catch (TimeoutException e) {
handleTimeout();
}
}
boolean shouldContinueWaiting() {
// Has the user already answered?
}
void handleInterrupt() {
// The user has answered. Dispose of this thread.
}
void handleTimeout() {
// User didn't answer in time
}
void sleep() throws InterruptedException {
Thread.sleep(SLEEP_DURATION_IN_MILLIS);
}
void getTime() {
return System.currentTimeMillis();
}
then you can start/restart the thread by:
t = new Thread(same as above...);
t.start();
and stop by:
t.interrupt();
We want to use the Timer class.
private Timer timer;
When you're ready for the timer to start counting -- let's say it's after you press a certain button -- do this to start it:
timer = new Timer();
timer.scheduleAtFixedRate(incrementTime(), 0, 100);
The first line is us creating a new Timer. Pretty standard. The second line, however, is the one I wanted you to see.
incrementTime() is a method that is called at the end of every "tick" of the clock. This method can be called whatever you want, but it has to return an instance of TimerTask. You could even make an anonymous interface if you want, but I prefer moving it off into its own section of code.
The 0 is our starting location. We start counting from here. Simple.
The 100 is how large a "tick" of the clock is (in milliseconds). Here, it's every 100 milliseconds, or every 1/10 of a second. I used this value at the time of writing this code because I was making a stopwatch application and I wanted my clock to change every 0.1 seconds.
As for your project, I'd suggest making the timer's task be your question switch method. Make it happen every 2000 milliseconds, or 2 seconds.
You can use a Handler.
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
//this will happen after 2000 ms
}
}, 2000);
Maybe this can help you:
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
// FIRE GAME OVER
handler.postDelayed(this, 2000); // set time here to refresh textView
}
});
You can fire your game over after 2000 milliseconds.
If you get the question correct -> remove callback from handler and reset it when the next question starts.
I am creating an app which is like a memory game. A button has an image resource from a drawable and I want to the background resource of a button to go back to its default background, say after 5 seconds.
Here is my code.
Collections.shuffle(ShapesArray);
this.myImg1=ShapesArray.get(0);
img1.setBackgroundResource(myImg1);
task = new TimerTask(){
#Override
public void run() {
// TODO Auto-generated method stub
img1.setBackgroundResource(android.R.drawable.btn_default);
}
};
Timer appear = new Timer();
appear.schedule(task, 5000);
img1.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
img1.setBackgroundResource(myImg1);
String txt = PName.getText().toString();
if(txt.equals("Heart")){
if(myImg1 == R.drawable.heart){
correct++;
img1.setBackgroundResource(android.R.drawable.btn_default);
}
}
However, after the 5 Seconds, the Activity force closes and goes back to previous activity. I'm kinda new to Android. Please help. :(
You can use either handler with post delay or can use count down timer ,here i am giving an example of count down and that is-
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
//This is when you click on each tick it came here after 1000 millisecond
}
public void onFinish() {
// After the time is experied so here can change image
Printer.setBackgroundResource(R.drawable.prntr);
}
}.start();
Thanks
Is there a way to continuously loop through a countdown timer? I have a basic timer of going though 60 seconds, then updating a text field and it's working, but I want to add the functionality: when it's counted down, to automatically restart again until the user cancels it? Maybe run it through a thread? Not sure how to handle it. Here is what I have, and again, this code works, but I can only stop and start the countdown timer, not do a continuous loop:
cdt = new CountDownTimer(60000,1000) {
public void onTick(long millisUntilFinished) {
tvTimer.setText("remaining : " + millisUntilFinished/1000 + " secs");
}
public void onFinish() {
tvTimer.setText("");
bell.start();
}
};
/***************On Click/Touch Listeners*******************/
btnNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tvTimer.setText("");
btnStart.setText("Start Timer");
SetImageView2(myDbHelper);
cdt.cancel();
}
});
btnStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (!TimerTicking){
cdt.start();
btnStart.setText("Stop Timer");
}
else {
tvTimer.setText("");
cdt.cancel();
btnStart.setText("Start Timer");
}
}
});
One very basic way to loop a CountDownTimer is to call start() in onFinished().
public void onFinish() {
...
start(); // Start this timer over
}
(Make sure you cancel your CountDownTimer in onPause() when you do this otherwise the timer might leak and keep firing in the background... Oops.)
However CountDownTimers has fundamental flaws (in my opinion): it often skips the last call to onTick() and it gains a few milliseconds each time onTick() is called... :( I re-wrote CountDownTimer in a previous question to be more accurate and call every tick.
The first value to the CountDownTimer() constructor, the total time to run, is a long and can hold a value approaching 300 million years. That ought to be long enough for most mobile applications. :-)
So just call it with cdt = new CountDownTimer(Long.MAX_VALUE, 1000) for a one second loop that will run continously.
I have this button which i want to set a timer to it so that the user do not have to click it everytime, such that it auto click this button every 20seconds. How do i set it?
Basically i am using a tabhost activity, so there're total of 3 tabs. In the first tab, there is this button which i need to click the button therefore i then able to retrieve informations from webservice and this webservice will update every time. When i click on other tabs and back to the first tab, i want it to be auto refresh.. Instead of clicking the button to refresh.
holder.btnClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
A more efficient way IMO is using ScheduledExecutorService:
private void doTheActualJobWhenButtonClicked() {
// put whatever you need to do when button clicked here
... ...
}
... ...
holder.btnClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// job triggered by user click button:
doTheActualJobWhenButtonClicked();
}
});
... ...
ScheduledExecutorService scheduleTaskExecutor= Executors.newScheduledThreadPool(1);
// This schedule a task to run every 20 seconds:
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
// job triggered automatically every 20 seconds:
doTheActualJobWhenButtonClicked();
}
}, 0, 20, TimeUnit.SECONDS);
UPDATE:
If your button click perform some UI update for example refresh text in a TextView, then simply wrap
your method call within runOnUiThread():
private void doTheActualJobWhenButtonClicked() {
myTextView.setText("refreshed");
}
ScheduledExecutorService scheduleTaskExecutor= Executors.newScheduledThreadPool(1);
// This schedule a task to run every 20 seconds:
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
// involved your call in UI thread:
runOnUiThread(new Runnable() {
public void run() {
doTheActualJobWhenButtonClicked();
}
});
}
}, 0, 20, TimeUnit.SECONDS);
Also you need shutdown ScheduledExecutorService properly before open next Activity or close your current Activity:
// Shut down scheduled task before starting next activity
if (scheduleTaskExecutor != null)
scheduleTaskExecutor.shutdownNow();
Intent intent = new Intent(getBaseContext(), NextActivity.class);
startActivity(intent);
... ...
public void onDestroy() {
super.onDestroy();
// Shut down scheduled task when closing current activity
if (scheduleTaskExecutor != null)
scheduleTaskExecutor.shutdownNow();
}
Hope this help.
Since you have a button, I assume that you have an ActionPerformed-type method at someplace.
Given that, you can do this:
public class AutoClick extends Thread {
// Time to wait in milliseconds
private long wait;
//Latency excepted
private long lat;
AutoClick(long time, long latency) {
wait = time;
lat = latency;
}
public void run() {
long start = System.getCurrentTimeMillis();
long current;
while(true)
current = System.getCurrentTimeMillis();
long step = (current-start) % 20000;
if(step <= latency || step >= wait-latency)
//call the action-performed method
}
}
Then create an instance of the thread and run it:
public AutoClick clicker = new AutoClick(20000);
clicker.run();