How to simulate a delay? - java

I want my Android app to do an auto demo, so after user clicks on a "Auto Demo" button, it will switch to a view and delay a second and click on a button on that view, then 2 seconds later click on another button on that screen .. so on, my java code looks like this :
private class AutoDemoListener implements View.OnClickListener
{
public void onClick(View v)
{
Is_AutoDemo_B=true;
Out("AutoDemoListener");
switchView(demoView, registrationView);
startRegistration();
Thread t = new Thread(new Runnable()
{
#Override
public void run()
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
try
{
registrationView.symbolButton[2][8].performClick();
Thread.sleep(1000);
registrationView.symbolButton[4][13].performClick();
Thread.sleep(2000);
registrationView.symbolButton[0][1].performClick();
Thread.sleep(1000);
registrationView.symbolButton[6][18].performClick();
}
catch (InterruptedException e) { e.printStackTrace(); }
}
});
}
});
t.start();
Is_AutoDemo_B=false;
}
}
But what it does now is : wait 4 seconds and simulate all 4 clicks at once, so there is no delay between each click, what's the right way to do it ?

You have to perform the delay in the background and post the results back to the UI each time.
You can do this using a Handler. The UI thread already comes with a prepared Looper that will allow you to easily use the Handler (other threads do not and require more setup).
The nesting of runnables would look nasty, so here it is with just adding increasing delays:
private class AutoDemoListener implements View.OnClickListener
{
public void onClick(View v)
{
Is_AutoDemo_B=true;
Out("AutoDemoListener");
switchView(demoView, registrationView);
startRegistration();
final Handler handler = new Handler();
registrationView.symbolButton[2][8].performClick();
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[4][13].performClick();
}
}, 1000);
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[0][1].performClick();
}
}, 3000);
handler.postDelayed(new Runnable() {
public void run() {
registrationView.symbolButton[6][18].performClick();
}
}, 5000);
handler.postDelayed(new Runnable() {
public void run() {
Is_AutoDemo_B=false;
}
}, 5100);
}
}
In Kotlin this could be much cleaner using a coroutine:
val autoDemoListener = View.OnClickListener {
Is_AutoDemo_B = true
Out("AutoDemoListener")
switchView(demoView, registrationView)
startRegistration()
CoroutineScope(Job() + Dispatchers.Main).launch {
registrationView.symbolButton[2][8].performClick()
delay(1000)
registrationView.symbolButton[4][13].performClick()
delay(2000)
registrationView.symbolButton[0][1].performClick()
delay(1000)
registrationView.symbolButton[6][18].performClick()
Is_AutoDemo_B=false
}
}

TimeUnit.SECONDS.sleep(1); see How do I make a delay in Java? is also in Android https://developer.android.com/reference/java/util/concurrent/TimeUnit
Maybe spawn new threads, sleep in these child threads and block the main threads until the child thread returns. #Tenfour04's answer is a similar concept to spawning threads i think ...

Related

How to start a thread if a button is idle?

I need a thread to start after 3 seconds of a button being idle, is there a simple way of doing it?
I'm building a counter app, the button triggers two counters, the total counter and the "tapping counter", the tapping counter helps keep track of the actual change of values, showing how many taps the user did, I need it to vanish after some seconds so the user can tap again.
for stuffs like that I usually use a Handler with a Runnable in order to do stuff after X milliseconds the user isn't doing a specific action.
First, create a runnable and a handler
final android.os.Handler handler = new android.os.Handler();
private Runnable runnable;
private final long DELAY = 3000; // how many milliseconds you want to wait
Then add the onClickListener:
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
Then, inside onClick event, remove callbacks and istantiate the handler again as follows:
if(runnable != null) {
// in this case the user already clicked once at least
handler.removeCallbacks(runnable);
}
runnable = new Runnable() {
#Override
public void run() {
//this code will run when user isn't clicking for the time you set before.
}
};
handler.postDelayed(runnable, DELAY);
Final result:
final android.os.Handler handler = new android.os.Handler();
private Runnable runnable;
private final long DELAY = 3000; // how many milliseconds you want to wait
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// all your previous stuffs
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(runnable != null) {
// in this case the user already clicked once at least
handler.removeCallbacks(runnable);
}
runnable = new Runnable() {
#Override
public void run() {
//this code will run when user isn't clicking for the time you set before.
}
};
handler.postDelayed(runnable, DELAY);
}
});
}
I hope this helps, for any question feel free to ask
Handler may work in this scenario, with a 3000 milisecond delay.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// do action
}
}, 3000);
At first, you create a Timer with a TimerTask(with your Thread) and schedule it to run after 3 seconds.
Every time the button is pressed, you reset the timer.
public class MyClass{
private Timer timer=new Timer()
private TimerTask task=new TimerTask(){
public void run(){
//your action
}
};
public void init(){
timer.schedule(task,3000);
}
public void onButtonClick(){
task.cancel();
timer.schedule(task,3000);
}
}

Android wait 1 minute without stopping thread

How do I wait one minute in my Android application without stopping the thread? I need to play a sound every minute for X rounds. I have all the code working except the waiting code.
public void startRounds(View v)
{
MediaPlayer mp = MediaPlayer.create(this, R.raw.ding);
mp.start();
EditText txtRounds = (EditText) findViewById(R.id.txtRounds);
rounds = Integer.parseInt(txtRounds.getText().toString());
oneSession();
}
private void oneSession()
{
//this needs to be replaced with my new wait one minute function
SystemClock.sleep(60000);
MediaPlayer mp2 = MediaPlayer.create(this, R.raw.ding);
mp2.start();
if (rounds != 1) {
rounds--;
oneSession();
}
}
Solved:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do something
}
}, 60 * 1000);
I am not sure if this is what you really want but it here do something will run after 60 * 1 seconds
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do something
}
}, 60 * 1000);
You can use Handler which will get executed without blocking thread.eg
handler.postDelayed(new Runnable() {
#Override
public void run() {
/**put your code inside this
* this method will get exceuted after 1 min without stopping thread
* same thing can be recursive based on your requirement*/
}
},60000);
Run the minute in another thread because on the UI Thread de sound will stop:
new Thread(new Runnable() {
#Override
public void run() {
try{
Thread.sleep(60000)
}catch(InterruptedExcpetion e){
}
}).start();

Editing a Button's colour in a nonUI thread (Android)

I've seen some similar questions and got some information but they stop shy of telling me enough to get it working.
What I'm trying to do is make a simple rhythm game where the player taps a button at regular intervals (ie. beats). I wanted to set up a way of signalling when to tap by having the button change colour, and since this would be a repeated task at regular intervals I want to use a timer object with a schedule method.
But when I try calling on this method it tells me that I can't change the UI in a non UI thread. I've tried a few ways to write a method in the main thread that I can call from the timer object but I get the same error every time. I'm assuming that I just have the wrong idea about what counts as being from the UI thread, so I was hoping someone could clear it up.
Here's a snippet of one way I tried it, just to show what my code looks like:
OnClickListener clickButton = new View.OnClickListener() {
public void onClick(View v) {
if (startBeat == 0){
startBeat = System.nanoTime();
timerStart.scheduleAtFixedRate((new TimerTask()
{
public void run()
{
flashButton();
}
}), 0, beatTime);
timerEnd.schedule(new TimerTask()
{
public void run()
{
unflashButton();
}
}, beatTolerance*2, beatTime);
return;
}
};
public void flashButton(){
beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1transparent_very));
}
public void unflashButton(){
beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1));
}
To be clear, this is all contained within my MainActivity class along with the OnCreate class.
if you are in an activity all you need to do is use runOnUiThread() and then place the code to change the ui element in there
public void flashButton(){
runOnUiThread(new Runnable() {
#Override
public void run() {
beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1transparent_very));
}
});
}
You cannot, under any circumstances, touch a UI object from a non UI thread.
You can accomplish your intent using Handler.sendMessageDelayed
UI can only be touched by the main thread. You should post the actions you are performing on the ui thread via handler or via runOnUiThread
Try something similar to this
timerStart.scheduleAtFixedRate((new TimerTask()
{
public void run()
{
//replace MainActivity with your activity
//if inside a fragment use getActivity()
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
flashButton();
}
});
}
}), 0, beatTime);
If you are in an Activity you could surround flashButton() with an runOnUiThread.
...
runOnUiThread(new Runnable(){
public void run(){
flashButton();
}
});
...
use android.os.Handler Class. Change your code as follows:
private Handler handler=new Handler();
public void flashButton(){
handler.post(new Runnable(){
public void run(){
beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1transparent_very));
}
});
}
public void unflashButton(){
handler.post(new Runnable(){
public void run(){
beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1));
}
});
}

Start an Activity from Splash Screen, should I use run() or runOnUiThread()?

I have a Splash Screen (Logo Activity) to show the company name for 3 seconds before app starts. I start Main Activity from a thread, here is the code:
public class Logo extends Activity {
Thread t;
public boolean dead = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.logo);
t = new Thread() {
public void run() {
try {
Intent i = new Intent(Logo.this, Main.class);
Thread.sleep(3000);
if (!dead) {
startActivity(i);
}
finish();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();
}
The Main Activity is called from a worked thread, is this correct? What are the differents with this code (using runOnUiThread)?
...
if (!dead) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Intent i = new Intent(Logo.this, Main.class);
startActivity(i);
}
});
}
...
I see no difference with this code in debug mode (The same threads, the same operation, etc.). Which is correct?
Starting an intent I think is not an UI operation. runOnUI thread runs UI operation on UI thread. So you can use either of thread (runOnUI or normal). May be normal thread will be good in this situation. But I would like to suggest you use timer instead.
To be honest, I don't like the Thread.sleep. PLease take a look at my solution:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
// Do your work here like... startActivity...
}
}, SPLASH_DURATION); // SPLASH_DURATION IS IN MILLISECONDS LIKE 3000
Also you can block the user to prevent the back key like this:
#Override
public void onBackPressed() {
// do nothing! disable user interaction!
}
You should use AsyncTask in "doInBackground" background thread and than sleep your thread(this thread not UIThread) "PostExecute" run on UI Thread than start your new activity
private class mSplashViewer extends AsyncTask<Void,Void,Void>{
protected void doInBackground(Void params){
Thread.currentThread().sleep(3000);
return null;
}
protected void onPostExecute(){
startActivity(...);
}
}

Android: Updating UI with a Button?

So I have some simple code but it seems to not be working.. any suggestions?
I just want an image to show after a button is pressed then become invisible after 2 seconds.
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
firstImage.setVisibility(ImageView.VISIBLE);
// delay of some sort
firstImage.setVisibility(ImageView.INVISIBLE);
}
}
The image never shows, it always stays invisible, should I be implementing this in another way? I've tried handlers.. but it didn't work, unless I did it wrong.
Never make your UI thread sleep!
Do this:
final Handler handler = new Handler();
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
firstImage.setVisibility(ImageView.VISIBLE);
handler.postDelayed(new Runnable(){
public void run(){
firstImage.setVisibility(ImageView.INVISIBLE);
}
}, DELAY);
}
}
Where you would set DELAY as 2000 (ms).
Well, you will need to add a delay between the two lines. Use a thread or a timer to do this.
Start a thread on click of a button. In the run method, change the ImageView's visibility to VISIBLE, then put the thread to sleep for n secs, and then change then make it invisible.
To call the imageView's setvisibility method, you will need a hanlder here.
Handler handler = new Handler();
handler.post(new Runnable() {
public void run() {
image.setVisibiliy(VISIBLE);
Thread.sleep(200);
image.setVisibility(INVISIBLE);
}
});
I know this question has already been answered, but I thought I would add an answer for people who like me, stumbled across this looking for a similar result where the delay was caused by a process rather than a "sleep"
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
firstImage.setVisibility(ImageView.VISIBLE);
// Run the operation on a new thread
new Thread(new Runnable(){
public void run(){
myMethod();
returnVisibility();
}
}).start();
}
}
private void myMethod() {
// Perform the operation you wish to do before restoring visibility
}
private void returnVisibility() {
// Restore visibility to the object being run on the main UI thread.
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
firstImage.setVisibility(ImageView.INVISIBLE);
}
});
}

Categories