For a side project of mine, I'm devoloping an android app with java. I don't know java a lot but i'm trying ^^.
The project is to have an Alarm at a random time in a certain range. The problem is that my chronometer and button freeze, but everything still works! Does anyone has maybe another solution for the thread.sleep ??
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void StartChrono(View view) {
final Chronometer chrono = (Chronometer)findViewById(R.id.chronometer1);
chrono.setBase(SystemClock.elapsedRealtime());
chrono.start();
//Tick();
}
public int RandomTime(int min, int max)
{
int random = max - min;
Random rand= new Random();
random = rand.nextInt(random)+min;
return random;
}
public boolean CheckUp(int randomtime,int chronotime)
{
boolean check = false;
if(randomtime== chronotime)
{
check = true;
}
return check;
}
public void Tick()
{
boolean check = false;
int randomtime = RandomTime(20,150);
int time=1;
do
{
check = CheckUp(randomtime,time);
time = time +1;
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Error - 000");
alertDialog.setMessage("Could not check!");
alertDialog.show();
}
}while(check == false);
if(check == true)
{
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Yuy");
alertDialog.setMessage("Switch!");
alertDialog.show();
}
}
}
I wouldn't use Thread.sleep(), I would use a Timer.
You can set a time and the Timer automatically calls the associated task.
In Android it would work something like this:
http://android.okhelp.cz/timer-simple-timertask-java-android-example/
I used it once myself, but that is some time ago.
Btw.:
You don't have to write a method to check for a boolean value.
This also works:
boolean check = 5>3;
System.out.println("check: " + check);//"check true"
I'd definately use a Handler for this task: http://developer.android.com/reference/android/os/Handler.html
A basic example would be this:
long timeDelay = 1000; // Set this to your random number.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do whatever you need to do after a specified interval.
}
}, timeDelay);
Instantiate the Handler inside your onCreate and keep the reference around so you can call it inside your method.
Just to clarify, why you can't use Thread.sleep() for "sleeping" a specific amount of time, is this: when you call Thread.sleep() you call it on the UI thread, so every component running on the UI thread (buttons, textfields and so on) will "sleep" for the given amount of time and hence you basically halt the whole application.
Also see the documentation for Thread.sleep:
Causes the thread which sent this message to sleep for the given
interval of time (given in milliseconds).
Related
Here,I have all the the id of record store in database in arraylist.My main point is How to Keep that Record For Some Seconds and then proceed further .
public class AuctionStart extends AppCompatActivity {
ArrayList<String> arr;
TextView tv;
int i;
DatabaseReference drf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auction_start);
tv = (TextView) findViewById(R.id.aucnm);
Bundle b = getIntent().getExtras();
if (null != b) {
arr = b.getStringArrayList("list");
}
else {
Toast.makeText(this, "Sorryy", Toast.LENGTH_SHORT).show();
}
}
}
after this suppose display arraylist first element in textview for 3 seconds then simultaneously all.
It's simple and straight forward. You can use postDelayed(). Here is the code snippet may help you, to achieve setTimeout() like thing,
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
// This will executed after 3 seconds
// Your Logic here
}
},
3000);
and here is the code snippet can help you to run on interval like setInterval
new Timer().scheduleAtFixedRate(new TimerTask(){
#Override
public void run(){
//This will execute after every 5 second untill timer cancel()
}
},0,5000);
For your case, you can do it as given,
if (null != b) {
arr = b.getStringArrayList("list");
int index = 0;
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask(){
#Override
public void run(){
tv.setText(arr.get(index));
if(index == (arr.size() - 1)){
t.cancel();
}else{
index++;
}
}
},0,3000);
}
else {
Toast.makeText(this, "Sorryy", Toast.LENGTH_SHORT).show();
}
Use rx java and rxfirebase and there is function in rx java will repeat the process again but I don’t recommend that you can eather use cloud function and add background service on firebase cloud to togle a key to update your data since it’s real time it will auto refresh and btw you need to make sure about both of the movements will cost you money 🤪
I have a button in my activity. When I press it, following method "ProcessNumbers()" is called. I need the functionality that "Processing..." text should be displayed in the textview first, then the loop should get processed, and when the loop finishes after 2-3 seconds, the textview should show "Processed" text. But this is not happening. When I click the button, loop runs first and after 2-3 seconds, the textview contains "Processed". Why the first step is missing where textview should contain "Processing..."?
private void ProcessNumbers()
{
TextView textViewProcessNumbers = (TextView) findViewById(R.id.textViewProcessNumbers);
textViewProcessNumbers.setText("Processing...");
int k = 0;
for (long i = 0; i <= 1000000000; i++)
{
k = 1;
}
textViewProcessNumbers.setText("Processed...");
}
Am I missing something here?
private void ProcessNumbers()
{
TextView textViewProcessNumbers = (TextView) findViewById(R.id.textViewProcessNumbers);
textViewProcessNumbers.setText("Processing...");
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 30000ms
textViewProcessNumbers.setText("Processed...");
}
}, 30000);
}
Use handler for delay. Hope it helps
You need to move that process to a background thread e.g. using an AsyncTask since textview won't get updated until you leave the main thread.
Executing long running operations on the UI thread is also not recommended and it might cause an Application Not Responding dialog to appear.
So
1. Set the label to Processing...
2. Start the AsyncTask with your process
2. When AsyncTask finishes update the label in onPostExecute
You can use CountDownTimer, after find text view add this code.
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
textViewProcessNumbers.setText("Processing...");
}
public void onFinish() {
textViewProcessNumbers.setText("Processed...");
}
}.start();
CountDownTimer(long millisInFuture, long countDownInterval)
Before I start I have looked at lots of threads including:
How to add time to countdown timer?
Android game countdown timer
But I just cant get my timer to work in the way I require. I want the timer to be counting down from say 30 and when and image is pressed (named imageview1 in this case) the timer adds 3 seconds to the timer to give it more time. I know you cannot essentially add the time while its running and you need to cancel and then start a new timer, The code I have so far is :
public void onClick(View v) {
// TODO Auto-generated method stub
//GlobalClass global = new GlobalClass();
Random rand = new Random();
CountDownTimer thetimer = new myTimer(millisInFuture, 1000);
switch(v.getId()) {
case R.id.buttonstart:
btnstart.setVisibility(View.INVISIBLE);
thetimer.start();
break;
case R.id.imageView1:
if (thetimer != null){
thetimer.cancel();
thetimer = new myTimer(countdownPeriod + 3000, 1000).start();
}
break;
with lots of other case references then :
public class myTimer extends CountDownTimer {
public myTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
timedisplay.setText("Time Left: " + millisUntilFinished / 1000);
countdownPeriod=millisUntilFinished;
}
#Override
public void onFinish() {
timedisplay.setText("Timer Finished");
started = false;
btnstart.setVisibility(View.VISIBLE);
}
}
I think the problem is its not cancelling the original timer so the label that shows the timer does some crazy things, like jumping around on different numbers both up and down as there would appear more than 1 class of thetimer. That is even though I have included the line thetimer.cancel(); The timer works fine if I just let it run to 0.
Any help would be great
You should not create your timer as a local in onClick. Instead create it as a global and start it somewhere else (in onCreate perhaps).
What happens with your current code is that whenever onClick is called a new timer is created and you then cancel the new timer - which has no effect on any previously created timer(s).
Try something like this:
public class MyActivity extends Activity {
CountDownTimer thetimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
thetimer = new myTimer(millisInFuture, 1000);
}
public void onClick(View v) {
Random rand = new Random();
switch(v.getId()) {
case R.id.buttonstart:
btnstart.setVisibility(View.INVISIBLE);
thetimer.start();
break;
case R.id.imageView1:
if (thetimer != null) {
thetimer.cancel();
thetimer = new myTimer(countdownPeriod + 3000, 1000).start();
}
break;
}
}
}
You will still have to keep track of the global time somewhere - i.e. the countDonwPeriod used to re-create the timer instance when an image is touched - it should probably be extracted from the timer before canceling it.
I recently began working with Java and am exploring Android development. I was trying to port over one of the Java programs I made, but I am having some difficulty with getting the java Timer to function the same way in Android. I read through a number of posts and they, for the most part, indicated that it would be better to use the Handler class in android as opposed to Timer.
This was my timer in Java:
playTimer = new Timer(1000/model.getFPS(), new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// do something
...
if( finished everything ) playTimer.stop();
}
});
And once a certain button was clicked, I would simply run "playTimer.start()" to start it.
As you can see, I had it set up so that the user could set the FPS they wanted (by simply setting the first parameter of the Timer class to 1000/model.getFPS()).
Now I've tried to do something similar in Android using handlers, but I am having some difficulty. It appears that the Handler ticks are not firing at the proper intervals. It seems that they are quite slow compared to what I need it to be. This is what I did in android so far:
public void startTimer() {
playHandler = new Handler();
startTime = System.currentTimeMillis();
playHandler.removeCallbacks(updateTimeTask);
playHandler.postDelayed(updateTimeTask, 0);
}
private Runnable updateTimeTask = new Runnable() {
public void run() {
// do something
...
if( finished everything ) playHander.cancel();
else {
playHandler.postDelayed(updateTimeTask, 1000/model.getFPS());
}
}
};
Excuse the semi-pseudocode. Can anyone shed any light? Thanks guys.
You can use a timer as below. The timer runs every second incrementing the counter. Displs the counter value in textview.
Timer runs on a different thread. SO you should set the text on the UI Thread.
The counter runs from 0 to 99. After 99 the timer is cancelled. Also cancel the timer when not required like in onPause().
public class MainActivity extends Activity {
TextView _tv,tv2;
Timer _t;
int _count=0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_tv = (TextView) findViewById( R.id.textView1 );
_t = new Timer();
_tv.setText(R.string.app_name);
_t.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
_count++;
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
_tv.setText(""+_count);
if(_count==99)
{
_t.cancel();
}
}
});
}
}, 1000, 1000 ); //change this value of 1000 to whatever you need.
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
_t.cancel();
}
}
If you decide not to use Timer (for whatever reason) you can just write a separate Thread that sleeps for x milliseconds and then wakes up and calls whatever Runnable you want it to call. That's going to be pretty precise. I have it working at the 10 millisecond level and it works quite nicely.
Just remember that it HAS to call a Runnable because a separate Thread can't have direct effect on anything on the main display thread.
public boolean keepPlayingAnimation = true
Handler h = new Handler()
Runnable updateDisplay = new Runnable(){
public void run(){
//do something in my display;
}
}
new Thread(){
public void run(){
while(keepPlayingAnimation){
try{
sleep(10);
}catch(Exception e){
}
h.post(updateDisplay);
}
}
}.start();
Just don't forget to set keepPlayingAnimation to false when you're done with this cause otherwise it will sit there running in the background for ever (or just about).
Take a look at Android Timer
It already has everything you need i guess. From ticking every 1 second to finish handly and so on.
Here is an example how to setup an TimerTask: setup
Not sure if you need such but i just remembered that i made this.
I'm feeling very, very stupid right now... I feel like I must be missing something really obvious.
I've encountered variations of this problem on multiple occasions now, however here is my current example -
When the activity is created, there will be a button marked Start and text set to --:-- next to it. I would like to have it so that when the button is pressed, a timer starts from one minute and displays the seconds remaining in the --:-- text as 00:59 etc. etc., and the text on the button changes to Pause. If the button is pressed when the timer is running, it pauses the timer and changes the text on the button to Start.
So I was using a boolean, timerRunning, in order to keep track of whether the timer was running or not. But if I try to change timerRunning within the onClickListener it gives an error and tells me to change timerRunning to final, and then once I do that it says "The final local variable timerRunning cannot be assigned, since it is defined in an enclosing type."
I'm sorry if this is unclear - I'm just really confused with where I should be declaring variables / how to access them etc. in Android, I don't really understand why I keep getting weird errors all the time.
Thanks.
public class Timing extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.timing);
Button bStartJammer = (Button) findViewById(R.id.buttonStartJammer);
CountDownTimer cdtJammerTimer;
long lJammerTotalMS = 60000;
final boolean timerRunning = false;
bStartJammer.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
timerRunning = true;
}
});
}
}
Without source context, it's tough to visualize what you're doing.
How are you defining your click handler? If it's an anonymous class, you'll run into the final issues--is your activity or handler so complex that it makes a separate class completely necessary?
In the previous question my click handler was implemented by the activity, so it has access to that instance's variables. A much-abbreviated skeleton of what I had been doing before not using the CountDownTimer:
public class FooTimer extends Activity implements View.OnClickListener {
private CountDownTimer timer;
private TextView timerDisplay;
private Button pauseButton;
private boolean timerRunning = false;
private boolean timerDone = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
pauseButton = (Button) findViewById(R.id.pause_button);
pauseButton.setOnClickListener(this);
timerDisplay = (TextView) findViewById(R.id.timer_display);
timerDisplay.setText(String.format("%d:%02d:%02d", hours, minutes, seconds));
timer = newTimer();
timerRunning = true;
timer.start();
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.pause_button:
toggleTimer();
break;
}
}
private void toggleTimer() {
if (timerRunning) {
timer.cancel();
pauseButton.setText(getResources().getString(R.string.resume_label));
timerRunning = false;
} else if (timerDone) {
finishActivity(0);
} else {
seconds += 1;
timer = newTimer();
timer.start();
pauseButton.setText(getResources().getString(R.string.pause_label));
timerRunning = true;
}
}
private CountDownTimer newTimer() {
millis = (minutes * 60 * 1000) + ((seconds + 1) * 1000);
return new CountDownTimer(millis, 1000) {
public void onTick(long millisUntilFinished) {
timerDisplay.setText(String.format("%d:%02d:%02d", hours, minutes, seconds));
}
public void onFinish() {
timerDisplay.setText("Finished");
timerRunning = false;
timerDone = true;
pauseButton.setText(getResources().getString(R.string.back_label));
}
};
}
}
(I took a bunch of stuff out, and added some really early code back in, so it's a bit of a mish-mosh, but the ideas are there.)
Your new OnClickListener(){..} is actually an anonymous class: http://mindprod.com/jgloss/anonymousclasses.html
Anonymous classes have access to class (static) and instance fields of enclosing class. So a solution is to have timerRunning defined as a field, i.e. define it outside of onCreate() method.
its not starting the code anywhere, your just setting it to true that its a timer. watch the tutorials here and they should really help you out. cornboyzandroid
Some of his earlier videos really describe how to do a timer pretty clearly and step by step. And he helps with global and local variables. around episode 6 or 7 just check his page out.