I want my alert to be appear for 15 minutes when user click button 5 times.Please help me I am not able to understand handler in android.
if(btn_count==5){
handler = new Handler();
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
alert("Your account has been blocked for 15 minutes due to 5 unsuccessfull attempts.");
btn_count=0;
} catch (Exception e) {
// error, do something
}
}
});
}
};
timer.schedule(task, 0, 60*1000);
try to put this in alert dialog method
Step 1 : change this
if(btn_count==5){
alert("Your account has been blocked for 15 minutes due to 5 unsuccessfull attempts.");
}
Step 2 : Put this in alert code
btn_count= 0;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dismiss();
}
}, 900000);
Try this
new Handler().postDelayed(() -> {
//Show the Alert here
}, 90000);
if(btn_count==5){
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.loader);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
new CountDownTimer(900000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
dialog.dismiss();
}
}.start();
}
First don't use Handler inside Timer only use Handler which are better.
Have one variable that stores clicks
private int clickCount = 0;
and in onClick() of your button do like this
#Override
public void onClick(View view){
if(v == btn_login && clickCount < 5){
if(WrongPassword){
clickCount++;
if(clickCount == 5){
showAlert();
}
}else{
clickCount = 0;
// put your login code here
}
}
}
private long mLastClickTime = 0
private void showAlert(){
mLastClickTime = SystemClock.elapsedRealtime();
alert("Your account has been blocked for 15 minutes due to 5 unsuccessfull attempts.");
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putLong("mLastClickTime", mLastClickTime);
editor.commit();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dismiss();
clickCount = 0;
}
}, 900000);
}
and finally in onCreate() you need to check that previously user have tried more than 5 times or not(in case user kills the app an come back immediately)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
Long oldLastClick = prefs.getLong("mLastClickTime", 0);
if (oldLastClick != 0) {
Long currentTime = SystemClock.elapsedRealtime();
if((currentTime < oldLastClick) < 90000){
clickCount = 5;
alert("Your account has been blocked for 15 minutes due to 5 unsuccessfull attempts.");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dismiss();
clickCount = 0;
}
}, (currentTime - oldLastClick));
return;
}
}
}
#Shivangi, I believe that CountDownTimer is best match to your requirement because you can update UI thread from there as well.
You can achieve this in following way:
Set a count so that you can have button click count.
if(btnClickCount == 5)
{
//Show alert to user
Toast.makeText(getBaseContext(), "You account locked for next 15 min.", Toast.LENGTH_SHORT).show();
//Pretended that you have login button like this.
//Disable login button so that user will not click this until it enabled again after so called 15 minute
btnLogin.setEnabled(false);
//Start count down timer from 15 minute like this
CountDownTimer countDownTimer = new CountDownTimer(900000, 1000) {
#Override
public void onTick(long millisUntilFinished)
{
//You can update your UI here if you want,like time remaining for re-login attempt. So that user UX appear good. It'll be called every second as I set it to 1000.
// You can user a dialog to show time remaining to unlock account and use this method to get formatted time
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)));
//Output will be like this 00:14:59
}
#Override
public void onFinish()
{
//Enable button as 15 minute lock period is over. and reset the button click counter
btnClickCount = 0;
btnLogin.setEnabled(true);
}
}.start();
}
You can break down this code into function as well.
Thanks
Related
I am using following code for using a button. I works.(sendBtn is a button in a fragment)
sendText = view.findViewById(R.id.send_text);
View sendBtn = view.findViewById(R.id.send_btn);
sendBtn.setOnClickListener(v -> send(sendText.getText().toString()));
Now i want to disable the button for 1 sec after a click
I found following solution but above code works "without onClick(View v)"method and without implementing View.OnClickListener in class. How to provide delay in such case..How code is working without onClick method.
#Override
public void onClick(View v) {
((Button) findViewById(R.id.click)).setEnabled(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
((Button) findViewById(R.id.click))
.setEnabled(true);
}
}, 1000);
}
});
Use this method when you want to interrupt user clicks:
private static long mLastClickTime = 0L;
public static boolean isOpenRecently() {
if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) {
return true;
}
mLastClickTime = SystemClock.elapsedRealtime();
return false;
}
Usage:
if (v.getId() == R.id.sendBtn) {
if (isOpenRecently()) return;
// Your logic
}
Basically you are using lambda in your code, where v->{} represents the onCLick(View v) function.
sendBtn.setOnClickListener(v -> send(sendText.getText().toString()));
You can do the following to disable the button for 1 second
void doOnSendButtonClick(View v){
//Send the message (your logic here)
send(sendText.getText().toString());
//Disable button
sendBtn.setEnabled(false);
//enable button after 1000 millisecond
new Handler(Looper.getMainLooper()).postDelayed(() -> {
sendBtn.setEnabled(true);
}, 1000);
}
And call this method when user clicks on the button
sendButton.setOnClickListener(view -> doOnSendButtonClick(view));
You could use a CountDownTimer.
CountDownTimewr timer = new CountDownTimer(1000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
// enable button
((Button) findViewById(R.id.click)).setEnabled(true);
}
}
#Override
public void onClick(View v) {
// disable btn and start timer of one second in millis
((Button) findViewById(R.id.click)).setEnabled(false);
timer.start();
}
});
Please try this way
Handler(Looper.getmainLooper()) and remove callback after you done your task inside runnable thread...also try to put this logic in any method outside in this class and call from setonclicklistener
Try the Timer.shedule with timertask
you can use runOnUIThread method inside where you can update UI.
you can also try to check the time difference of click and enable again in looping like while.
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.
So I have this "hack" to have a toast duration a little bit longer:
// Toast...
zanimivosti = new Toast(getApplicationContext());
zanimivosti.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
zanimivosti.setView(layout);
new CountDownTimer(4000, 1000) {
public void onTick(long millisUntilFinished) {
zanimivosti.show();
}
public void onFinish() {
zanimivosti.show();
}
}.start();
PROBLEM: When a user go to another intent, it can happen that the toast reaper again in new intent.
In my case CountDownTimer.cancel(); won't work
ALTERNATIVE:
In my toast I am displaying news every time the user lunch the app. I would also take in consideration a better solution whit a toast that when a user click on it disappear or when new intent is called also disappear.
Should I use a pop up dialog? Can I make it disappear when user clicks on it?
At the end I did it like this:
Toast zanimivosti;
int cas = 4000;
int perioda = 1000;
boolean boolean_toast = true;
CountDownTimer timer;
timer = new CountDownTimer(time, perioda) {
public void onTick(long millisUntilFinished) {
zanimivosti.show();
}
public void onFinish() {
if (boolean_toast == true) {
zanimivosti.show();
} else {
}
}
}.start();
And stoping the timer with stopping/cancelling all the possible things:
boolean_toast = false;
time = 0;
perioda = 0;
timer.cancel();
zanimivosti.cancel();
I need to make every second the health to go down by "1" after going the health under 20 or is equal to 20 to show the "alertDialog" i don't have any errors in the code. The problem is crushing after the "Health" passed the border/limit the application is crushing, i don't know why is that happening, is there someone to help me with it ?
I also make sure that there is one time show of the "alertDialog" with boolean but doesn't help...
Thanks in advice :)
Code:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
Health -= 1;
if (Health <= 20) {
if (!canSeeWarnDialog) {
final AlertDialog alertDialog2 = new AlertDialog.Builder(
MainActivity.this).create();
alertDialog2.setTitle("Im hungry");
alertDialog2.setMessage("The dog health is going low "
+ "\ngive him some food");
alertDialog2.setButton("Got it",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
alertDialog2.cancel();
}
});
alertDialog2.show();
canSeeWarnDialog = true;
return;
}
}
}
}, 1000, 1000);//TimeUnit.SECONDS.toMillis(1));
Why don't you use a CountDownTimer ? It seems more suitable to your task and it handles all the callbacks on the UI thread for you.
You need a CountDownTimer.
When taking "length" as amount of Health in miliseconds (*1000 -> 30 max health => 30000 length).Current health should be millisUntilFinished/1000.
boolean notified = false;
new CountDownTimer(length, 1000) {
#Override
public void onTick(long millisUntilFinished)
{
if(millisUntilFinished <= 20 && !notified)
{
final AlertDialog alertDialog2 = new AlertDialog.Builder(
MainActivity.this).create();
alertDialog2.setTitle("Im hungry");
alertDialog2.setMessage("The dog health is going low "
+ "\ngive him some food");
alertDialog2.setButton("Got it",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
alertDialog2.cancel();
}
});
alertDialog2.show();
notified = true;
}
}
#Override
public void onFinish()
{
//Health is 0.
notified = false; // For next time.
//if you want to restart -> retrieve full health:
this.start();
}
};
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.