When the app launch, I have a button (btn1) and a timer starting (long start = System.nanoTome();).
Now, two things can happen:
either the button is clicked at any time BEFORE the time limit of 1 minute (do some code_A then)
or the timer (long elapsedTime = System.nanoTome() - start;) reaches the time limit of 1 minute (do some code_B then)
I have tried lots of various combinations, but I stuck on the logic with regard to the time dimension and the if/while or whatever loop that would express/trigger BOTH the time condition OR the action condition (button btn1 pressed) in parallel.
Does anybody have an idea? That would be of great help.
You can use the CountDownTimer: https://developer.android.com/reference/android/os/CountDownTimer
CountDownTimer countDownTimer = new CountDownTimer(10000, 1000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
codeB();
}
}.start();
Button button = new Button(this);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
countDownTimer.cancel();
codeA();
}
});
This will create a timer with the length of 10 seconds and the onTick method is called every 1 second.
new CountDownTimer(timerLength, tickInterval)
To further visualize your question in the comments, whether the timer stops or not:
In this screenshot, I've let the timer run out. The timer was set to 5 seconds and after 5 seconds onFinish() was called, as seen by the message.
In this screenshot, I've cancelled the timer through the onClickListener, as you can see there is no message in the center, thus onFinish() hasn't been called.
You can use CountDownTimer and handle the state there, then invoke the proper method depending on the state:
Kotlin version:
class MyCountdownTimer: CountDownTimer(60000, 1000) {
private var state: CountdownState = CountdownState.IDLE
override fun onFinish() {
state = CountdownState.FINISHED
}
override fun onTick(p0: Long) {
if(state == CountdownState.IDLE) {
state = CountdownState.COUNTING
}
}
fun getState(): CountdownState {
return state
}
}
enum class CountdownState {
IDLE, COUNTING, FINISHED
}
And in your code:
val countdownTimer = MyCountdownTimer()
btn1.setOnClickListener {
countdownTimer.start()
}
btn2.setOnClickListener {
if(countdownTimer.getState() == State.RUNNING) {
callMethodWhenRunning()
} else if (countdownTimer.getState == State.FINISHED) {
callMethodWhenFinished()
}
}
Java version:
import android.os.CountDownTimer;
public class MyCountdownTimer extends CountDownTimer {
private CountdownState state = CountdownState.IDLE;
public MyCountdownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long l) {
if(state == CountdownState.IDLE) {
state = CountdownState.COUNTING;
}
}
#Override
public void onFinish() {
state = CountdownState.FINISHED;
}
public CountdownState getState() {
return state;
}
}
enum CountdownState {
IDLE, COUNTING, FINISHED
}
and usage:
MyCountdownTimer timer = new MyCountdownTimer(60000, 1000);
btn1.setOnClickListener(view -> {
timer.start();
});
btn2.setOnClickListener(view -> {
if(timer.getState() == State.RUNNING) {
callMethodWhenRunning();
} else if (timer.getState == State.FINISHED) {
callMethodWhenFinished();
}
});
Related
i have code block as below shown. for examaple Can i work this code three times?
when i used for loop or other loops. it isnt performed i wanted process.
new CountDownTimer(3000,1000) {
#Override
public void onTick(long l) {
gostertext.setText(""+l/1000);
durumgoster.setText("KOŞ..");
}
#Override
public void onFinish() {
gostertext.setText("KOŞU bitti YÜRÜ");
CountDownTimer counter=new CountDownTimer(3000,1000) {
#Override
public void onTick(long l) {
gostertext.setText(""+l/1000);
durumgoster.setText("YÜRÜ..");
}
#Override
public void onFinish() {
gostertext.setText("bitti");
}
}.start();
}
}.start();
when a counter ended, other counter will start that will perform three times.
i writed code as over shown that is worked but i want to perform three times.
Can we solve this problem?
why not make the loops contents into 1 void,
and call it three times?
You could do something like(untested):
int countCounter = 0;
CountDownTimer mCountDownTimer = new CountDownTimer() {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
if (countCounter < 3){
countCounter++;
// cancel the counter and restart it!
mCountDownTimer.cancel();
mCountDownTimer.start();
}
}
};
How do i set a timer for TextView ? This code keeps crashing my app
final TextView textwel = (TextView) findViewById(R.id.welcometext);
Thread timer = new Thread() {
public void run() {
try {
// this should sleep for 4 seconds
sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
textwel.setText("Welcome");
}
};
start the timer
timer.start();
That won't work.
Since the new thread that you create is not the UI thread, you can't update the UI (setting the text of a text view) on that thread.
A better way to do this would be to use the android.os.Handler class. It has a postDelayed method that will execute a Runnable with a delay. Here is the docs.
Alternatively, you can use this Timer class I wrote, which encapsulates a Handler instance and has a simple interface:
import android.os.Handler;
public class Timer {
private Handler handler;
private boolean paused;
private int interval;
private Runnable task = new Runnable () {
#Override
public void run() {
if (!paused) {
runnable.run ();
Timer.this.handler.postDelayed (this, interval);
}
}
};
private Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startTimer () {
paused = false;
handler.postDelayed (task, interval);
}
public void stopTimer () {
paused = true;
}
public Timer (Runnable runnable, int interval, boolean started) {
handler = new Handler ();
this.runnable = runnable;
this.interval = interval;
if (started)
startTimer ();
}
}
Gist
You would probably use it like this:
Runnable run = new Runnable() {
public void run() {
textwel.setText("Welcome");
}
};
Timer timer = new Timer(run, 4000, true);
P.S. setting the textview's text to "Welcome" every 4 seconds is pointless.
You can you use CountDownTimer api to update TextView timer which is very easy to use and convenient.
Here is the simple example:
TextView tvTime = (TextView)findViewById(R.id.tv_time);
CountDownTimer countDownTimer = new CountDownTimer((durationInMilis * 60000), 1000) {
#Override
public void onTick(long millisUntilFinished)
{
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millisUntilFinished)),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)));
tvTime.setText(hms);
}
#Override
public void onFinish()
{
// Do your other task on finish
}
}.start();
This code this will update tvTime text every second and run for sepecified amount of time in durationInMilis. Output will look like hh:mm:ss e.g 01:23:57
If you don't want show anything on update then leave onTick() callback blank and update your TextView in onFinish(). Just pass value to parameter durationInMilis for which you want to run timer.
If you have any doubt please feel free to comment.
//use it, its easy and simple
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
textwel.setText("Welcome");
}
}, 4000);
why are you using textview??
Chronometer is a class provided by android that implements a simple timer so my suggestion is use it in place of textview.
here is the official link
try this , it will work 100% and also UI will not stuck
Thread timer = new Thread() {
public void run() {
try {
// this should sleep for 4 seconds
sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// after sleep call a UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
textwel.setText("Welcome");
}
});
}
};
I dont find an answer on google or i dont get the right words for it.
So the SpeechRecognizer works fine.
But when i hear the beep (i use it without the google dialog) and i say nothing for about 3 seconds or more, its like the recognizer do nothing and fade away, no second beep to hear, no onResult(), no EndofSpeech.
So what happend when the Recognizer is listening and you say nothing? Which method get fired?
EDIT: After all it works, big thanks to OpiateFuchs and his realy good comments and answers. I edit the simplified code that way, that you guys can see how to make it.
onPartialResult() is called often even if you say nothing, but when this happen the partialResult String is empty, so if its empty you know nothing was spoken.
(Idea from OpiateFuchs)
Thats my simplified Code which is important for the Recognizer:
public Constructor (){
speech = SpeechRecognizer.createSpeechRecognizer(context);
speech.setRecognitionListener(this);
recogIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recogIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "de");
speech.startListening();
}
public void startListening(){
speech.startListening(recogIntent);
if(timerRunning==false){
setcdt();
mCountDownTimer.start();
timerRunning=true;
}
}
#Override
public void onReadyForSpeech(Bundle params) {
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float rmsdB) {
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onEndOfSpeech() {
Toast.makeText(c, "work", Toast.LENGTH_SHORT);
//too see if its called
}
#Override
public void onError(int error) {
}
#Override
public void onResults(Bundle results) {
ArrayList<String> matches = results
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
Toast.makeText(c, matches.get(0), Toast.LENGTH_LONG).show();
speech.cancel();
analyse(matches.get(0));
m.next(); //calls the Recognizer again
}
#Override
public void onPartialResults(Bundle partialResults) {
ArrayList<String> matches = partialResults
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if(matches.get(0).length() == 0){
m.tv.append("nothing"); //show on textview
}
else{
m.tv.append("cancel timer "); //show on textview
mCountDownTimer.cancel();
hasSpoken = true;
timerRunning = false;
}
}
#Override
public void onEvent(int eventType, Bundle params) {
}
//innerclass
public class FinishSpeechRecognizerTimer extends CountDownTimer {
public FinishSpeechRecognizerTimer(long startTime, long interval){
super(startTime,interval);
}
#Override
public void onFinish(){
timerRunning = false;
if (hasSpoken==false){
m.tv.append("nospeak ");
speech.cancel();
m.tv.append("listen again after no speak ");
startListening();
}
}
#Override
public void onTick(long millisUntilFinish){
}
}
public void setcdt(){
startTime = 5000;
interval = 4000; //want no onTick - interval > startTime
timerRunning = false;
hasSpoken = false;
mCountDownTimer = new FinishSpeechRecognizerTimer(startTime, interval);
}
For this discussion I try to provide an example from scratch which should lead you into the right direction. As said in the comments, it seems that the SpeechRecognition does not stop from itself if nothing is said, so you simply could implement a CountDownTimer for example and finish the SpeechRecognizer after a certain time:
make global SpeechRecognizer (like you have done), boolean and CountdownTimer objects :
private SpeechRecognizer speech;
private boolean hasSpoken=false;
private CountDownTimer mCountDownTimer;
private long startTime = 30000L;
private long interval = 1000L;
private boolean timerRunning = false;
extend the CountDownTimer class:
public class FinishSpeechRecognizerTimer extends CountDownTimer{
public FinishSpeechRecognizerTimer(long startTime, long interval){
super(startTime,interval);
}
#Override
public void onFinish(){
if(hasSpoken==false){
speech.cancel();
}
timerRunning=false;
}
#Override
public void onTick(long millisUntilFinish){
//do whatever you want to do
}
}
initialize
speech = SpeechRecognizer.createSpeechRecognizer(yourContext);
mCountDownTimer = new FinishSpeechRecognizerTimer(startTime, interval);
start it and at the same time start the CountDownTimer:
speech.startListening(recogIntent);
if(timerRunning==false){
mCountDownTimer.start();
timerRunning=true;
}
And as soon as something is spoken, set the boolean value hasSpoken to true and cancel the timer:
#Override
public void onBeginningOfSpeech() {
hasSpoken=true;
mCountDownTimer.cancel();
timerRunning=false;
}
As I said, it´s from scratch, can´t guarantee that this is working. This example starts the CountDownTimer for 30 seconds and checks every second if something is spoken. How long you want to wait is up to you.
EDIT
Turns out that in some cases the onBeginOfSpeech() method is called multiple times without anybody is speaking. For everyone who is interested:
instead of doing that stuff in onBeginOfSpeech(), you can use the method onPartialResult():
#Override
public void onPartialResults(Bundle partialResults) {
ArrayList<String> matches = results
.getStringArrayList(SpeechRecognizer.RESULT_RECOGNITION);
if(matches.size()==0){
hasSpoken=false;
}else{
hasSpoken=true;
mCountDownTimer.cancel();
timerRunning=false;
}
}
Hi i am trying to cancel a countdown timer in On-tick function, It is working fine in lollipop but not working in Kitkat and below. How cancel it from a OnTick() function.
private void startTimer(final int minuti) {
countDownTimer = new CountDownTimer(60 * minuti * 1000 + sec * 1000,
500) {
#Override
public void onTick(long leftTimeInMilliseconds) {
CountDownTimer.cancel();
}
#Override
public void onFinish() {
}
}.start();
}
Somehow if you call countdowntimer.cancel of a CountDownTimer object in its own onTick method it won't work!
The simplest way to solve your problem is defining another CountDownTimer, same as the main one, in order to check the condition to call countdowntimer.cancel. The point is that you are calling objects cancel method from outside of its own onTick method.
Check the example below:
CountDownTimer countdowntimer;
CountDownTimer assist;
long millisuntillfinish = 10000;
int interval = 100;
countdowntimer = new CountDownTimer(millisuntillfinish, interval) {
#Override
public void onTick(long millisUntilFinished) {
// if(true) countdowntimer.cancel(); (doesnt work)
}
#Override
public void onFinish() {
}
};
assist = new CountDownTimer(timertillfinish, timerinterval) {
#Override
public void onTick(long millisUntilFinished) {
if (true) {
countdowntimer.cancel();
}
}
#Override
public void onFinish() {
assist.cancel();
}
};
I know this question is more than 6 years old, but calling super.cancel(); within onTick() did the trick for me.
Leaving this here for the next unfortunate soul looking for an answer to this question.
ie.
new CountDownTimer(5000, 1000) {
public void onTick(long millisUntilFinished) {
if(someCondition)
super.cancel();
}
public void onFinish() {
//do something else
}
}.start();
new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
if (((millisUntilFinished/1000)%5)==0){ //every 5 sec
if(true)
{
this.cancel();
}
}
}
public void onFinish() {
//do somethhing
}
}.start();
I have been looking around and I have found this post where they call to the cancel() method in the onTick() using an alternative to the Android countDownTimer.
I had also this problem, and I created a global variable of a countDownTimer and I called to the cancel method in the activity when I needed, like myCountDownTimer.cancel().
private CountDownTimer mCountDownTimer;
private CountDownTimer createTimer(){
return new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
//do what you want
}
public void onFinish() {
//do what you want
}
}.start();
}
In your activity call:
mCountDownTimer = this.createTimer();
And if you want to cancel it:
mCountDownTimer.cancel();
I am new to Android Development and trying to make little Game.
CountDownTimer.cancel() is not working for me.
Any Idea?
Thank Your for your Answer!
CountDownTimer cdt = new CountDownTimer(120000, 1000) {
public void onTick(long millisUntilFinished) {
maxTime = (int) (millisUntilFinished / 1000);
timer.setText(String.valueOf(maxTime));
}
public void onFinish() {
}
};
if (startTimer == true) {
cdt.start();
} else {
cdt.cancel();
}
I have to do an assumption right here because the code doesn't show much! apparently you are using the countDownTimer inside your onCreate as an inner class so that will trigger the timer when startTimer == true and it would create the object no matter what! I guess it would be better to create a global instance of CountDownTimer.
And write your code in this way:
if(startTimer == true) {
cdt = new CountDownTimer(120000, 1000) {
public void onTick(long millisUntilFinished) {
maxTime = (int) (millisUntilFinished / 1000);
timer.setText(String.valueOf(maxTime));
}
public void onFinish() {
}
}.start(); //start the countdowntimer
}
else{
cdt.cancel();
}
Boolean Myboolean = true;
CountDownTimer MyCountDownTimer = new CountDownTimer(10000, 1000)
{
#Override
public void onFinish()
{
}
#Override
public void onTick(long millisUntilFinished)
{
Log.i("onTick" , String.valueOf((millisUntilFinished / 1000) % 60));
if(!Myboolean ) { cancel(); }
}
}.start();
i had this issue , the CountDownTimer will not cancle with (MyCountDownTimer.cancel();) , the best way is to use Boolean , set the Boolean to false to cancel the CountDownTimer. in any place you want (Myboolean =false;)