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
Related
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.
I am Stuck here with this application in android. In my application i am trying to implement a progressbar which shows timer for certain seconds. When the Button is clicked the timer should refresh and again start from 0 in progressBar. For this I am using Thread.
The Problem is, When I Click the button the Thread calls the timer function and each time the thread is getting faster and faster. I couldn't resolve it and not having any idea what is going in background.
This is my code for Timerfunction
public void setTimer()
{
prog=0;
progress.setProgress(prog);
if(flag){
t= new Thread(new Runnable(){
public void run()
{
while(prog<100)
{
prog+=1;
handle.post(new Runnable(){
public void run()
{
progress.setProgress(prog);
if(prog==progress.getMax()&& flag){
call_fun();
}
}
});
try
{
Thread.sleep(time);
}
catch(InterruptedException e)
{
Log.i("Error", null);
}
}
}
});
t.start();
}
}
I called this function in another function called RandomGeneration. If the button is clicked the randomgeneration is called and the set timer is activated everytime. But the progressbar is running faster after every click. It is constantly running in the same specific time. For example if it runs for 3 seconds in the first click, its running 2 seconds in the second click and getting faster considerably.
Can anyone please try to find what is happening in this code.
Thanks in advance..!!
From what I see a new Thread is being created everytime you click the button.
Maybe try to check if t is already running and if so update it's logic to set progress to 0?
Also, what does if(flag) do?
I just want to call a function after every 3secs on click of a button
What is going wrong here-
galleryBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final Handler handler = new Handler();
for(int i = 0;i<3;i++){
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do something after 5s = 5000ms
viewAnimator.showNext();
}
}, 3000);
}
}
});
You don't actually say what goes wrong but I'll take a wild guess that nothing happens (i.e. no animations) and the reason for that is probably that your Handler is being GC'd long before it gets to handle anything. Try keeping moving 'handlers' scope from local variable to class member.
(Also note that, even when it works, all 3 of your functions will run at more or less the same time. If you want them to run 3 seconds apart you should change the '3000' to 'i*3000'.)
I'm working on an app that synchronizes some graphic UI events with an audio track. Right now you need to press a button to set everything in motion, after onCreate exits. I'm trying to add functionality to make the audio/graphical interaction start 10 seconds after everything is laid out.
My first thought is, at the end of onCreate, to make the UI thread sleep for 10000 miliseconds using the solution here and then to call button.onClick(). That seems like really bad practice to me, though, and nothing came of trying it anyway. Is there a good way to implement this autostart feature?
Never ever put sleep/delay on UI-thread. Instead, use Handler and its postDelayed method to get it done inside onCreate, onStart or onResume of your Activity. For example:
#Override
protected void onResume() {
super.onResume();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do whatever you want here
}
}, 10000L); //the runnable is executed on UI-thread after 10 seconds of delay
}
Handler handler=new Handler();
Runnable notification = new Runnable()
{
#Override
public void run()
{
//post your code............
}
};
handler.postDelayed(notification,10000);
Yes, putting the UI thread to sleep isnt a good idea.
Try this
private final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.schedule(task, 10, TimeUnit.SECONDS);
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.