Wait before the activity is fully displayed - android

I'm currently having a problem when a button is pressed before the activity is fully displayed. My app is a questionnaire type that spawns buttons as options for the question. If I press the button repeatedly and fast, a black screen will randomly occur but the activity will still display afterwards.
My current solution is to put a delay before I set the event listener to the buttons.
private Runnable task = new Runnable() {
public void run() {
addEventHandlerToButtons();
}
};
And put this in onCreate or onPostCreate
Handler handler = new Handler();
handler.postDelayed(task, 500);

Related

How to wait button clicks for a while in android

I am developing an application for blinds.
I have 4 screen sized buttons (overlapped). Every step of program one button will be clickable and every button has more than one job.
My program starts with a voice (Android TTS engine). Like "please touch screen to do x". After this step I want to wait 3 seconds for button click, if button is not clicked vocalize "please touch screen to do y" and wait 3 seconds again for job y. (x and y is first button's jobs).
Button should do one of them according to touching screen. But how can I wait 3 seconds for button click and continue to vocalize next options and wait 3 seconds again.
If first button is clicked, it will disappear-button 2 will be clickable- and TTS engine will start to vocalize second buttons options. Application will be work like this but I am stuck in waiting button clicks part.
I would advise you to use android.os.Handler instead. In your case you could do something like this:
public void onCreate() {
this.handler = new Handler()
playTheVoiceOfThingX()
viewToTap.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
doThingX();
}
});
handler.postDelayed(new PrepareThingYTask(), 3000);
}
class PrepareThingYTask() implements Runnable {
viewToTap.setOnClickListener(new OnClickListener(){
#Override
public void onClick() {
doThingY();
}
});
handler.postDelayed(new PrepareThingZTask(), 3000);
}
class PrepareThingZTask() implements Runnable {
....
}
A good reminder, the runnable executed by the handler can be executed in UIThread, so no heavy work on it, or create a different looper to run it.
Regards
You could solve your problem with busy wait.
So after you first vocalized "please touch screen..." you would start a background thread which waits for a specific amount of time, like so:
new Thread(new Runnable() {
public void run() {
Thread.sleep(3000);
runOnUiThread(new Runnable() {
#Override
public void run() {
//vocalize
}
});
}
}).start();
As you can see, from within the thread a new runnable is started after 3 seconds which again runs on the UI Thread. This, because I think I remember that you should make such sound-things (depending on your method of how to play the file / sound) only from the UI Thread.
However, this is just an idea and I could not test-run my code!
But I hope I inspired you!
Regards
Me

Android postDelayed does not delay

I have the Problem that my Android app does not delay a second (or 10 seconds), if I use the postDelayed method..
Basically I would like my program to wait one second after I clicked the button, then update the text on my textview ("READY"), wait another 2 seconds, then update the textview again ("SET") and then it should start another activity (not yet implemented :-) ).
With my code, the programm starts and after I click the button the textview shows the last text ("SET") immediately.. It just does not wait.
What am i doing wrong?
Here is my code:
public class MyCounterActivity extends Activity {
private long mInternval = 100000;
private Handler mHandler;
private Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
//updateInterval(); //change interval
startRepeatingTask();
}
};
void startRepeatingTask(){
mHandler.postDelayed(mStatusChecker, mInternval);
//mStatusChecker.run();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gym_counter);
final TextView tv1 = (TextView) findViewById(R.id.fullscreen_content);
final Button startButton = (Button) findViewById(R.id.startbutton);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final long up;
EditText textUp = (EditText) findViewById(R.id.editTextUp);
up = Integer.parseInt(textUp.getText().toString());
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//
}
},1000);
Log.d("after 1 runnable", "whaaat");
tv1.setText("Ready");
handler.postDelayed(new Runnable() {
#Override
public void run() {
//
}
}, 2000);
Log.d("after 2nd runnable", "whaaat 2");
//startRepeatingTask();
tv1.setText("SET");
}
});
}
I also tried to run it with the runOnUiThread() (within the onClick(View v) but with with the same result). I expected it to wait 1 second (startRepeatingTask()) and then runs the loop and waits several seconds...
runOnUiThread(new Runnable() {
#Override
public void run() {
startRepeatingTask();
for (int u = 0; u < up; u++){
startRepeatingTask();
}
}
}
});
Hope my description makes sense :-).
Thank you for your help!
EDIT:
I was now able to find a solution for my first problem. The answer from #mad in this post helpded me: How to start a different activity with some delay after pressing a button in android?
(Thats probably the same thing that #laalto tried to tell me. Thanks for the hint!)
In the onClick()
tv1.setText("READY");
mHandler.postDelayed(mDelay1, 2000);
And then the Runnable
private Runnable mDelay1 = new Runnable() {
#Override
public void run() {
if (tv1.getText()=="READY")
tv1.setText("SET");
}
};
BUT:
If i want to refresh the text on my Textview after every second, how do i do that? I cant just call mHandler.postDelayed() several times.. Any help is appreciated.
When you call postDelayed(), it just places the Runnable in a queue and returns immediately. It does not wait for the runnable to be executed.
If you need something to happen after a delay, put the code in the run() method of the runnable.
Whenever you call something like Thread.start(), handler.postDelayed, view.postDelayed, AsynchTask, TimerTask .. you enter the world of threading or you might call it parallel computing.
So there can be multiple threads ("codes") running at the same time.
When you are inside your Activity it is running in a Thread that is calld UI-thread or main thread. All graphics is handled in that thread and that thread alone.
Do NEVER wait in the UI-thread!
Example: you have a button that switches color from say gray to yellow on pressing it. Now you enter a Thread.sleep(10000); - waiting 10 seconds at the start of your onClick.
You will then see that the button stays yellow (=pressed) for 10 seconds even if you only pressed very shortly. Also: if you overdo it android os will become angry and post the user if he wants to force-close your app.
So what happens on handler.postDelayed?
Android will very quickly open a thread that runs in the background parallel to your UI thread. So in some nanoseconds it has done that and will execute the next command in UI thread (in the example above it is Log.d). In the background it will wait and count the millis until time is up. Then any code that is inside the runnable.run method will again be executed in the ui-thread after the wait.
Note also: postDelayed will not be super precise with the wait time as usually the ui-thread is quite buisy and when the wait time is up it may have something else to do. Your runnable code will be added to a queue and executed when ui-thread is ready again. All this happens without you having anything to do about it.
Also:
Remember to work with try/catch inside the runnable.run as many things can happen while waiting - for example user could press Home button closing your app - so the ui-element you wanted to change after the wait could already been destroyed.

Specify what classes I want my handler to run

I have a class with a handler in it and it works fine, but it then hits a class where I want the handler to stop if the timer has not already timed out. So if the handler reaches the end it should go to the Drunk class, if the user reaches the end of the app before the handler goes off, the handler should not go off. I have it going off at the end of the app but I don't want it too. It should stop once it hits the end of the app.
THANKS!
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run()
{
toDrunk();
}
},20000);
public void toDrunk(){
Intent i = new Intent(this, Drunk.class);
startActivity(i);
}
You need to remove that message from the handler when the activity is stopped. You can do that either by storing the runnable in some variable and then removing it using removeCallbacks or by posting the runnable with some token and then removing all messages with that token using removeCallbacksAndMessages.

Android button disable till the Toast is seen

I have a button which shows a progress dialog, on end of progress dialog, a toast is shown.
I want the button to be diabled when the progress dialog and the toast are seen on the UI. i.e. after the toast is gone i want my button to be enabled again
Can anybody suggest what to do
As soon as you show the toast, set the button clickable to false, and start this timer task. The method of the class Timer namely schedule(), is such that it is executed after the provided time. In this case i passed the time as Toast.LENGTH _SHORT
final Handler handler = new Handler();
Timer time = new Timer();
time.schedule(new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
your_button.setClickable(true);
}
});
}
},Toast.LENGTH_SHORT); //// If your toast is for length short.
Put the below code before the progress dialog starts
Button myBtn=findViewById(R.id.button1);
myBtn.setVisibility(View.INVISIBLE);
//myBtn.setEnabled(false);
After Toast.makeText() is called, put the below code:
myBtn.setVisibility(View.VISIBLE);
//myBtn.setEnabled(true);
Note that setVisibility will make the button visible/invisible, setEnabled(false) will turn your button to non-clcikable mde.

How can I make a imageview visible, 5 sec pause, invisible, 5 sec pause and so on

I have an imageView and want it to work like this:
ImageViewer visible
5 second pause
image view invisible
5 second pause
ImageViewer visible
and so on ...
How do I do that? I have tried sleep but it freezes the whole program in 5 seconds. I just want to affect my imageView.
I'm not an Android programmer, but, as a general advice, I'd say you should perform the sleep, better said the waiting, on another thread and execute at the end of the waiting period, on the main thread, a method that toggles the visibility of your imageview.
Getting into more specific detail, I'd say you must use a Handler object because you cannot update most UI objects while in a separate thread. When you send a message to the Handler it will get saved into a queue and get executed by the UI thread as soon as possible:
public class MyActivity extends Activity {
// Handler needed for callbacks to the UI thread
final Handler mHandler = new Handler();
// Create runnable for posting
final Runnable mUpdateUIState = new Runnable() {
public void run() {
updateUIState();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
[ . . . ]
}
protected void startToggle() {
// Fire off a thread to do the waiting
Thread t = new Thread() {
public void run() {
Thread.Sleep(5000);
mHandler.post(mUpdateUIState);
}
};
t.start();
}
private void updateUiState() {
// Back in the UI thread -- toggle imageview's visibility
imageview.setVisibility(1 - imageview.getVisibility());
}
}
or, a snippet of a shorter version,
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
imageview.setVisibility(1 - imageview.getVisibility());
}
}, 5000);
using the postDelayed method, that incorporates the delay within the message posting logic.
Use an AlphaAnimation on the ImageView with a 10 second duration going from alpha 100 to 0 and back to 100 again.
Then use a repeact count of INFINITE.
You can use an interpolator to produce a much pleasant effect while the ImageView appears or disappears.

Categories

Resources