Android ProgressBar: loading with Timer - android

Update:
This post was from when I was learning android with android 2.2, be sure to check if this is compatible with the api level you are working with.
Done alot of looking around for how to load progress bar with a timer, I've tried to use methods posted but always would get a pointer exception and or the testing app would crash at start up.
my question is, lol has anyone ran across any tutorials or examples on how to do this? I'm thinking all i need is a while loop but haven't seen that done on a timer yet. I'm a complete noob but am slowly but surely learning
My Timer
final Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
d.dismiss(); //MY DIALOG WINDOW
t.cancel();
}
}, 7000);
this is one i have tried to get to work but think i have done more damage then good with it
isRunning = false;
// handler for the background updating
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
total = total - 1;
String perc = String.valueOf(total).toString();
a.setText(perc + " SECONDS until close");
bar.incrementProgressBy(25);
}
};
super.onStart();
// reset the bar to the default value of 0
bar.setProgress(0);
// create a thread for updating the progress bar
Thread background = new Thread(new Runnable() {
public void run() {
try {
for (int i = 4; i < 20 && isRunning; i++) {
// wait 1000ms between each update
Thread.sleep(1000);
handler.sendMessage(handler.obtainMessage());
}
} catch (Throwable t) {
}
}
});
isRunning = true;
// start the background thread
background.start();
hoping someone might be able to shed some light on this for me,, as always sorry for the short generic question, just looking to find out how to load progress bar with timer
tahnks again for any and all help

Use a android.os.CountDownTimer
countDownTimer = new CountDownTimer(length_in_milliseconds,period_in_milliseconds) {
private boolean warned = false;
#Override
public void onTick(long millisUntilFinished_) {
progressBar.progress = (length_in_milliseconds-millisUntilFinished_)/lenght_in_milliseconds*100.0;
}
#Override
public void onFinish() {
// do whatever when the bar is full
}
}.start();

My answer from here:
You could use an ObjectAnimator to animate the progress of the ProgressBar:
ObjectAnimator animation = ObjectAnimator.ofInt(pb, "progress", 0, 100);
animation.setDuration(5000);
animation.setInterpolator(new DecelerateInterpolator());
animation.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) { }
#Override
public void onAnimationEnd(Animator animator) {
//do something when the countdown is complete
}
#Override
public void onAnimationCancel(Animator animator) { }
#Override
public void onAnimationRepeat(Animator animator) { }
});
animation.start();

Related

How to update a textview frequently with a spesific time delay?

I need to update a TextView frequently with a specific time delay in the android studio. The code is below. Thank you.
Edit: I also need to end the loop with a button click or with an "if" control.
//INFLATION CALCULATION !!!
/**
* This method calculates Inflation value.
*/
public void calculateInflation() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
}
}, delay*12);
}
Call the same method inside the runnable in order to keep the loop going
Use a flag in order to be able to stop the loop: shouldCalculate
private boolean shouldCalculate = true; // set to false when you want to end the loop
public void calculateInflation() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
if (shouldCalculate) {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
calculateInflation();
}
}
}, delay*12);
}
private Runnable updateTimerThread = new Runnable() {
public void run() {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
customHandler.postDelayed(this, 0);
}
};
public void startTimer() {
//timer
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
}
public void stopTimer() {
//timer stops
customHandler.removeCallbacks(updateTimerThread);
//timer ends
}
make a reference of runnable thread , start it using startTimer() and remove thread using stopTimer() as you said on a button click or up on a specific conditions .Also you can change the postDelayed milliseconds as ur wish
Try below code. This will do the trick. If you find any problem please let me know.
public void calculateInflation() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
if(shouldRepeat)
calculateInflation();
}
}, delay*12);
}
And second approach can be CountDownTimer. Make a method as shown in below code
public void timerTask(final int loopTime){
//Loop time is the actual time for repeatation
new CountDownTimer(loopTime, 1000) {
public void onTick(long millisUntilFinished) {
//this tells you one second is passed
}
public void onFinish() {
//here on time finish you need to define your task
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
//call the same method again for looping
timerTask(loopTime);
}
}.start();
}
Simplest way. Here updateRunnable calls itself with delay. Make updateRunnable as global variable to access from anywhere.
Runnable updateRunnable = new Runnable() {
#Override
public void run() {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
handler.postDelayed(this, UPDATE_TIME);
}
};
Start handler. Here we start handler immediately without delay.
handler.postDelayed(updateRunnable, 0)
Stop handler
handler.removeCallbacks(updateRunnable)
By the way don't forget to stop handler on onDestroy()

Running backgound thread every X seconds (Android Studio)

I have a code that plays 5 sounds with 1 second delay between the sounds and I want this part of code to be executed every 5 seconds (so it will run in a row so far as a boolean variable is true, and when it becomes false the tread run stopped - I have a button to both start and stop this executions). Everything works perfectly, but the issue is that I can't get rid of the 5 seconds delay in the first time I click the button, so when I first click, the sounds beggins only after 5 seconds. How can I make it start right away and only after the first time start taking the delays?
Here is the button onClick code:
public void clickHandlerStartTempo(final View view) {
if (!tempoOn) {
Toast toast = Toast.makeText(getApplicationContext(), "Start Tempo!", Toast
.LENGTH_SHORT);
toast.show();
tempoOn = true;
final Handler handler = new Handler();
final int delay = 5000; //milliseconds
handler.postDelayed(new Runnable() {
public void run() {
if (tempoOn) {
runCode(view);
handler.postDelayed(this, delay);
}
}
}, delay);
} else {
Toast toast = Toast.makeText(getApplicationContext(), "Stop Tempo!", Toast
.LENGTH_SHORT);
toast.show();
tempoOn = false;
}
}
And here is the runCode method:
public void runCode(View view) {
Runnable runnable = new Runnable() {
#Override
public void run() {
playSound(0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 4; i++) {
if (tempoOn) {
playSound(1);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
return;
}
}
}
};
Thread thread = new Thread(runnable);
Log.i(TAG, "runCode: Thread id = " + thread.getId());
thread.start();
}
I'm new to android development and any help would be very much appreciated.
Thanks.
First you need to playsound without thread after that you will execute your reaming 5 second logic stop thread after 4 count.
public void onStartPress(){
playSound();
someMethod();
}
public void someMethod(){
Handler uiHandler = new Handler(Looper.getMainLooper());
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
playSound();
someMethod();
}
},1000);
}
Don't use actual Threads unless you really want to do something off the Ui thread. Most of the time you do want to keep things on the Ui thread.
For simple repeating tasks, you can easily repurpose the CountDownTimer class. Often with an (almost) infinite run time or Long.MAX_VALUE (292 million years). The fist onTick happens immediately after starting.
private CountDownTimer mTimer;
private void start() {
if (mTimer == null) {
mTimer = new CountDownTimer(Long.MAX_VALUE, 5000) {
#Override
public void onTick(long millisUntilFinished) {
// start a beeping countdown
new CountDownTimer(5000, 1000) {
private int state = 1;
#Override
public void onTick(long millisUntilFinished) {
playSound(state);
state = state + 1 % 2;
}
#Override
public void onFinish() {
playSound(0);
}
}.start();
}
#Override
public void onFinish() { /* ignore, never happens */ }
};
mTimer.start();
}
}
private void stop() {
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}

Android: Handler and Timer inside a RecyclerView is not working properly

In a chatting window I have a feature like self destructing message after a duration. For which I have a class which shows burning animation after the duration. While sending text the handler and timer I used in the below class is working fine for 2-3 times then some animation discrepancy is found like the fire isn't starting in exact location.
Apart from that while sending a file from file chooser fragment when it returns to the recyclerview of the chatwindow nothing happens until I touch the screen and scroll it a bit. While debugging I noticed that the first time when bindview is called after sending a file the handler and timer is not executing properly. Instead if I navigate back and enter the chatwindow again it's working perfectly. It burns the filemessage perfectly then.
The burner class:
public class Burner {
private static final TaggedLogger logger = new TaggedLogger("Burner");
public static void burnMessage(final TextMessageViewHolder holder, final BurnerListener listener) {
final int DURATION = 3000;
if (!holder.isBurning) {
final Handler handler = new Handler(Looper.getMainLooper());
final Animator.AnimatorListener animatorListener = new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
logger.log("onAnimationStart");
}
#Override
public void onAnimationEnd(Animator animator) {
listener.onBurnFinished();
}
#Override
public void onAnimationCancel(Animator animator) {
}
#Override
public void onAnimationRepeat(Animator animator) {
}
};
holder.isBurning = true;
holder.fireAnimationHolder.setVisibility(View.VISIBLE);
holder.fireAnimationHolder.measure(0, 0);
Activity activity = (Activity) ChatProperties.getChatWindowContext();
if (activity != null) {
final ParticleSystem particleSystem = new ParticleSystem(activity, 48, R.drawable.fire_2, DURATION)
.setSpeedByComponentsRange(-0.025f, 0.0f, -0.06f, -0.08f)
.setAcceleration(0.00003f, 0)
.setInitialRotationRange(30, 45)
.addModifier(new AlphaModifier(255, 0, 200, 1000))
.addModifier(new ScaleModifier(0.5f, 2f, 0, 1000));
holder.fireAnimationHolder.post(new Runnable() {
#Override
public void run() {
holder.fireAnimationHolder.measure(0,0);
int fireAnimationHolderWidth = holder.fireAnimationHolder.getWidth();
// logger.log("fireAnimationHolderWidth = " + fireAnimationHolderWidth);
particleSystem.emit(holder.fireSource, 12);
holder.fireSource.animate().translationXBy(fireAnimationHolderWidth).setStartDelay(500).setDuration(DURATION).setListener(animatorListener).start();
holder.fireSourceController.setPivotX(0);
holder.fireSourceController.animate().alpha(1f).scaleX(1f).setDuration(DURATION).start();
}
});
new Timer().scheduleAtFixedRate(new TimerTask() {
int elapsedTime = 0;
#Override
public void run() {
elapsedTime += 300;
if (elapsedTime >= DURATION) {
handler.post(new Runnable() {
#Override
public void run() {
particleSystem.cancel();
}
});
this.cancel();
} else {
handler.post(new Runnable() {
#Override
public void run() {
particleSystem.updateEmitPoint(holder.fireSource, Gravity.CENTER);
}
});
}
}
}, 100, 300);
}
}
}
This burnMessage method is called from the bindview of the TextMessageViewholder's bindview method and FilemessageViewHolder extends TextMessageViewHoler class.
In TextMessageViewHolder's bindview method this function is called if it's a self destructing message:
private void handleMessageBurning(final Message message) {
if (message.imBurnTime > 0 && BurnMessageHelper.animatedBurnMessageEntryMap.containsKey(message.callerId)) {
Log.e("BurnThread","message to be burned");
Burner.burnMessage(this, new BurnerListener() {
#Override
public void onBurnFinished() {
if (ChatProperties.isGroupChat) {
DataHelper.getInstance().deleteGroupMessage(Target.target, message.callerId);
} else {
DataHelper.getInstance().deleteMessage(Target.target, message.callerId);
}
BurnMessageHelper.animatedBurnMessageEntryMap.remove(message.callerId);
isBurning = false;
}
});
} else {
fireAnimationHolder.setVisibility(View.GONE);
}
}
What is happening here? Does the thread of the timer can't run in main thread here due to some reason? Please help. Thanks.
N.B. I tried this in Marshmallow, Nougat and Oreo.

How to refresh an android view?

I am writing an app, where one of my views need to blink by the use of a timer constantly, but I have trouble with making it blink.
Here's my handler code
#SuppressWarnings("All")
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
try {
circle.setVisibility(View.VISIBLE);
Thread.sleep(100);
circle.setVisibility(View.INVISIBLE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
So i am sending an empty message to the handler with some INTERVAL constantly, and I want the image to get visible for 100 milliseconds and then hide again. But the problem is, until the method is finished, my UI elements won't get refreshed. How I do this?
Thanks in advance.
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
if(circle.isVisible()){circle.setVisibility(View.VISIBLE);}
else{
circle.setVisibility(View.INVISIBLE);
}
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if(msg.what == 1) circle.setVisibility(View.VISIBLE);
if(msg.what == 2) circle.setVisibility(View.INVISIBLE);
}
};
then send message 1 & 2 somewhere.
Here's an example of runnable that toggles visibility and infinitely reposts itself, delayed every 100 miliseconds. The problem that you are having is you are stopping the main UI thread, so nothing else is going to happen and your program is probably freezing right? Anyways, this is one style of solution. Another might be to do the posting in another thread.
final Handler mHandler = new Handler();
final View circle = ....;
Runnable blink = new Runnable() {
#Override
public void run() {
int vis = circle.getVisibility();
if(vis == View.VISIBLE){
circle.setVisibility(View.INVISIBLE);
}else{
circle.setVisibility(View.VISIBLE);
}
mHandler.postDelayed(this, 100);
}
};
mHandler.post(blink);
An alternative to the above solutions (Handler, Thread ...) is to create an Animator and rely on Androids flexible animation capabilities.
In this code-snippet you animate directly on the visibility-property of your View, whereas you need to define a custom TimeInterpolator (which only return two distinct values 0.0 and 1.0) as shown:
final ObjectAnimator anim = ObjectAnimator.ofInt(circle, "visibility",
View.VISIBLE, View.INVISIBLE);
anim.setRepeatMode(Animation.REVERSE);
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(1000);
anim.setInterpolator(new TimeInterpolator() {
#Override
public float getInterpolation(float input) {
return Math.round(input);
}
});
anim.start();

Countdown Timer which shows on the UI with AsyncTask

I'm trying to implement a Countdown Timer which shows on the UI,
I thought this was a clean and elegant solution but Logcat throws
AndroidRuntime(3282): java.lang.RuntimeException: An error occured while executing doInBackground()
,
private class UpdateCountdownTask extends AsyncTask<Long, Long, Void> {
#Override
protected Void doInBackground(Long... millisUntilFinished) {
new CountDownTimer(millisUntilFinished[0], 1000) {
#Override
public void onTick(long millisUntilFinished) {
publishProgress(millisUntilFinished);
}
#Override
public void onFinish() {
((TextView) findViewById(R.id.answer)).setText(answer);
}
};
return null;
}
#Override
protected void onProgressUpdate(Long... millisUntilFinished) {
super.onProgressUpdate(millisUntilFinished);
((TextView) findViewById(R.id.timer)).setText(""
+ millisUntilFinished[0] / 1000);
}
}
Still don't fully understand threads. Can anyone tell me what I'm doing wrong?
Thanks.
UPDATE: Very Sorry. I am an absolut incompetent. I had forgotten to call the metod start() on the counter. :P
I finally went for implementing the countdown with the CountDownTimer by itself. Sill don't know if this actually runs on a separate thread or not but it works now.
CountDownTimer myCounter = new CountDownTimer(millisUntilFinished, 1000) {
#Override
public void onTick(long millisUntilFinished) {
((TextView) findViewById(R.id.timer)).setText(""
+ millisUntilFinished / 1000);
System.out.println("I am ticking");
}
#Override
public void onFinish() {
}
};
myCounter.start();
I think the problem is the onFinish() method inside CountDownTimer. Here you're modifiying the UI thread, and you cannot do this from a background thread. So you have to put ((TextView) findViewById(R.id.answer)).setText(answer); inside onPostExecute() method. I mean:
protected void onPostExecute(String result) {
super.onPostExecute(result);
((TextView) findViewById(R.id.answer)).setText(answer);
}
I hope this works.
You will not be able to connect the UI when doing somthing in background.In my opinion what you want is possible if you use a thread.This will make your work much more easier.A small piece of code is shown below.I hope this may help you.I am trying to set an image instead you can settext.Here i had done using a thread and a handler.Its impossible to connect the UI inside the thread.In assynctask When you are doing something in background you are compleatly inside the thread.Thats why you are getting a error here.Otherwinse you can do it in Postexecute()
Thread animator = new Thread() {
public void run() {
int i = 0;
try {
sleep(2000);
while (i < 4) {
sleep(50);
handler.sendMessage(handler.obtainMessage(i));
i++;
}
} catch (Exception e) {
}
}
};
animator.start();
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
animatedimage.setImageResource(R.drawable.sub1);
} else if (msg.what == 1) {
animatedimage.setImageResource(R.drawable.sub2);
} else if (msg.what == 2) {
animatedimage.setImageResource(R.drawable.sub3);
} else if (msg.what == 3) {
animatedimage.setImageResource(R.drawable.sub4);
}
}
};
Have you consider using Handler to update UI every second?
checkout http://developer.android.com/resources/articles/timed-ui-updates.html

Categories

Resources