runnable with countdown - java

I am trying to use a runnable to count down from 30s to 0, then run a method, then restart. I cannot seem to get this working right. Seems like a very convoluted solution for a simple task...
tvHeatCD is a TextView that should update every sec to show "5s" if 5 seconds remain etc
reduceHeat() is the method that should run every 30 seconds (matching conditions shown)
stopHeatTimer() is just calling handler.removeCallbacks(..) and heatTimerRunning = false
public void checkHeatTimer() {
RealmResults<Heat> heatList = realm.where(Heat.class).equalTo("theheat","theheat").findAll();
ht = heatList.get(0);
if(ht.getHeat() !=0) {
if(!heatTimerRunning) {
final int[] countdown = {30};
tvHeatCD.setVisibility(View.VISIBLE);
heatRunnable = new Runnable() {
#Override
public void run() {
heatTimerRunning = true;
if (!realm.isClosed()) {
countdown[0]--;
if(countdown[0] == 0) {
if (ht.getHeat() != 0) {
Crashlytics.setInt("heat", ht.getHeat());
reduceHeat("normal",20);
stopHeatTimer();
checkHeatTimer();
} else {
Crashlytics.setInt("heat", 0);
tvHeatCD.setVisibility(View.GONE);
stopHeatTimer();
}
}
tvHeatCD.setText(countdown[0] + "s");
heatHandler.postDelayed(heatRunnable, 1000);
} else if (realm.isClosed()) {
recreate();
}
}
};
heatHandler.postDelayed(heatRunnable, 30000);
}
} else {
tvHeatCD.setVisibility(View.GONE);
}
}
Appreciate any help...thank you!

Related

Second method runs only after I press button twice

The problem is that the method runs only after I press button second time, but the goal is to work for both methods one after another when I press button for the first time.
The first method is runThreadWork(); and after that runThreadRest(); when the first is completed.
This is the part for the button.
btnStartTimer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(workMinutes > 0 || workSeconds > 0){
runThreadWork();
}else if(isTimerCompleted){
runThreadRest();
}
}
});
That's is the part for the method, basically both methods are the same in logic, but only change are variables for values, except TextView variable isn't changed for both methods, I want to use one TextView to show the output from both methods one after another.
private void runThreadWork() {
new Thread() {
public void run() {
while (workMinutes > 0 || workSeconds > 0) {
while (workSeconds > 0) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
workSeconds--;
String timeFormatedCountDownWork = String.format("Work time: " + "%02d:%02d", workMinutes, workSeconds);
txtTimeCountDown.setText(timeFormatedCountDownWork);
if(workSeconds == 0 && workMinutes > 0){
workMinutes--;
workSeconds = 60;
}
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
isTimerCompleted = true;
}

replay morsecode with flashlight?

I'm trying to build a Morse-Code App which can replay Morse with the built in Flashlight. So I tried a few things, one of them slightly worked, but not how it should.
So essentially I type in a Message, let's say "hello". It translates to
.... . .-.. .-.. ---
Then I want to replay that by tapping a Button.
I've tried out different things. This was my first attempt:
public void onPlayflash(View view) throws InterruptedException, CameraAccessException {
if (result == null) {
output.setText("ERROR");
} else {
currentposition = 0;
if (currentposition < result.length()) {
String c = String.valueOf(result.charAt(0));
if (c.equals("-")) {
//timeinmillis = 1000;
//setTimer();
flash.setTorchMode(flash.getCameraIdList()[0], true);
Thread.sleep(2000);
flash.setTorchMode(flash.getCameraIdList()[0], false);
} else if (c.equals(".")) {
//timeinmillis = 500;
//setTimer();
flash.setTorchMode(flash.getCameraIdList()[0], true);
Thread.sleep(1000);
flash.setTorchMode(flash.getCameraIdList()[0], false);
} else {
Thread.sleep(2000);
}
currentposition += 1;
}
}
}
This didn't work. It just said:
I/Choreographer: Skipped (*always a random number over 1000 here*) frames! The application may be doing too much work on its main thread.
Then I tried
public void onPlayflash(View view) throws InterruptedException, CameraAccessException {
if (result == null) {
output.setText("ERROR");
} else {
for (int i = 0; i < result.length(); i++) {
String c = String.valueOf(result.charAt(i));
if (c.equals("_")) {
flash.setTorchMode(flash.getCameraIdList()[0], true);
Thread.sleep(2000);
flash.setTorchMode(flash.getCameraIdList()[0], false);
Thread.sleep(500);
} else if (c.equals(".")) {
flash.setTorchMode(flash.getCameraIdList()[0], true);
Thread.sleep(1000);
flash.setTorchMode(flash.getCameraIdList()[0], false);
Thread.sleep(500);
} else {
Thread.sleep(1500);
}
}
}
}
This kinda worked, but it still says
I/Choreographer: Skipped (*always a random number over 1000 here*) frames! The application may be doing too much work on its main thread.
Actually the replay starts fine, but then it starts to struggle and skips parts of the iteration.
As you can see, I also experimented with android.os.CountDownTimer, but that didn't work out aswell. I only got one flash and then it stopped.
As you might see, I'm not that experienced yet '^^
Hope you can help me. Thanks in advance!
try again with CountDownTimer, but using recursion and passing a list of time to wait
private void test(List<Integer> resultTimeList, Integer count) {
flash.setTorchMode(flash.getCameraIdList()[0], true);
new CountDownTimer(resultTimeList.get(count), 500) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
new CountDownTimer(500, 500) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
flash.setTorchMode(flash.getCameraIdList()[0], false);
test(resultTimeList, count++);
}
}.start();
}
}.start();
}

Putting Delay in Android (Java)

I want to put delay of around 60 seconds in my code. I have used the following code, to put some delay; but it doesn't behave as expected.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Calling my function after 15 seconds delay.
}
}, 15000);
p.s. : I don't want to use Thread.sleep(), as it creates hindrance in normal operation of application.
You can try CountDownTimer.
// You can change millisInFuture and countDownInterval according to your need.
long millisInFuture = 60000;
long countDownInterval = 1000;
new CountDownTimer(millisInFuture, countDownInterval) {
#Override
public void onTick(long l) {
// Method call according to countDownInterval.
// For E.g we are taking 1000 so this method call every 1 second.
}
#Override
public void onFinish() {
// When 60 second completed call this method.
// Do your logic here.
}
}.start();
Actual thing you want to do like this.
long millisInFuture = 60000;
long countDownInterval = 1000;
int counter = 0;
new CountDownTimer(millisInFuture, countDownInterval) {
#Override
public void onTick(long l) {
// Method call according to countDownInterval.
// For E.g we are taking 1000 so this method call every 1 second.
}
#Override
public void onFinish() {
// When 60 second completed call this method.
// Do your logic here.
counter++;
if (counter == 1) {
// Call your 1st function
} else if (counter == 2) {
// Call your 2nd function
} else if (counter == 3) {
// Call your 3rd function
} else if (counter == 4) {
// Call your 4th function
} else if (counter == 5) {
// Call your 5th function
}
if (counter < 5) {
start();
}
}
}.start();

Calling a method every certain time and stop calling it on a certain condition in Android

I have a method called check in my Java class in Android and I call it every 30 seconds using the following method . My problem is that I want to stop calling it when a variable called stopFlag is equal to 1 but I'm unable to do that using timer.cancel().
Here is my method:
public void callAsynchronousTask()
{
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
check(currentDistance);
} catch (Exception e) {
Log.e(TAG,e.getMessage());
}
}
});
}
};
if( stopFlag==1){
timer.cancel();
timer.purge();
return;
}
else
timer.schedule(doAsynchronousTask, 0, 30000); //execute in every 30000 ms
}
// check method
public void check(double oldDistance)
{
currentDistance=measureDistance(myLoc.getLatitude(),myLoc.getLongitude(),RetrieveStationId.getStation_lat(),RetrieveStationId.getStation_lon());
if(currentDistance>=0 && currentDistance <200)
{
Log.e("Diff",Double.toString(oldDistance-currentDistance));
joined=0;
Join.setBackgroundResource(R.drawable.circle_button);
StateListDrawable drawable = (StateListDrawable) Join.getBackground();
drawable.setColorFilter(Color.rgb(238,238,238),PorterDuff.Mode.MULTIPLY);
updateMarker();updateCamera();
stopFlag=1;
}
else if(oldDistance-currentDistance>0)
{
Log.e("Diff",Double.toString(oldDistance-currentDistance));
joined=1;
Join.setBackgroundResource(R.drawable.circle_button);
StateListDrawable drawable = (StateListDrawable) Join.getBackground();
drawable.setColorFilter(Color.rgb(100,100,100),PorterDuff.Mode.MULTIPLY);
}
UpdateLocation updateLocation = new UpdateLocation(this);
updateLocation.execute(latitude, longitude,iden,Integer.toString(request),destination,Integer.toString(joined));
updateMarker();
updateCamera();
}

System.currentTimeMillis() returns same timestamp

I need to calculate time between two time. System.currentTimeMillis() returns same value everytime when it called in Thread.
My code is:
#Override
protected void onCreate(Bundle savedInstanceState) {
// Other codes..
start_sec = Math.round(System.currentTimeMillis()/1000);
fin = false;
runThread();
// Other codes..
}
private void runThread() {
new Thread() {
public void run() {
while (i++ < 61) {
if (!running) return;
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(!fin){
int len = Math.round(System.currentTimeMillis()/1000) - start_sec;
Log.d("current time: ",String.valueOf( Math.round(System.currentTimeMillis()/1000)));
Log.d("difference is: ", String.valueOf(len));
if(len < 0 && len > 58){
fin=true;
}
timerec.getLayoutParams().width = metrics.widthPixels *(60- len)/60;
timerec.requestLayout();
}
else{
end_game();
running= true;
}
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
Here is the logs:
...
D/current time:: 1492337024
D/difference is:: 0
D/current time:: 1492337024
D/difference is:: 0
....
It returs same "time". What is the solution?
take time as long. and don't divide it by 1000. the time difference is fraction of seconds.that's why it is showing the same time as you are rounding it.
the difference between two cycle in a while loop is so much less than a second and when your calculating the difference by seconds (you divide current millisecond with 1000) it makes the same second and the difference is 0 seconds.
try to print difference in milliseconds (without dividing).
Try this:
#Override
protected void onCreate(Bundle savedInstanceState) {
// Other codes..
start_sec = System.currentTimeMillis();
fin = false;
runThread();
// Other codes..
}
private void runThread() {
new Thread() {
public void run() {
while (i++ < 61) {
if (!running) return;
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(!fin){
int len = System.currentTimeMillis() - start_sec;
Log.d("current time: ",String.valueOf( System.currentTimeMillis()));
Log.d("difference is: ", String.valueOf(len));
if(len < 0 && len > 58){
fin=true;
}
timerec.getLayoutParams().width = metrics.widthPixels *(60- len)/60;
timerec.requestLayout();
}
else{
end_game();
running= true;
}
}
});
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
Math.round() causes the problem.
long len = System.currentTimeMillis()/1000 - start_sec;
Log.d("current time: ",String.valueOf(System.currentTimeMillis()/1000));
Log.d("difference is: ", String.valueOf(len));
This code works altought dividing.

Categories

Resources