I played a little around with CountDownTimer. However, for a special app I need the following functionality:
Start CountDownTimer with random runtime
Beep when finished
Wait 5 Seconds
Beep again
GOTO 1.
This procedure should be startet with a button and should also be canceled with a button. I found post here with a looped CountDownTimer, but this doesn't work with random runtime.
Okay, I'm not going to give you the code. That's your homework. I will however explain how the countDownTimer will work.
Once you've set up the CDT class create a new object.
private static myCDT newTime;//static makes sure there's only one instance of the variable in the entire program
newTime = new myCDT(randNum*1000, 1000);
Say randNum is 10, then the count down is for 10 seconds.
To generate the random number find out what you want the max limit to be. I'm assuming it to be 50. So the CDT will have an option from 0-50s.
int randNum=50*Math.random();
If you want to exclude 0 and want the minimum to be 1s
int randNum=1+49*Math.random();
Now also set a boolean variable for the button. The first time it's clicked let it be set to true. Use this variable as the condition in a while. Now, if the user clicks the button again, set the variable to false. Call the cancel() function for your CDT object newTime. Now call onFinish() function for your CDT. This will bring back flow of control to the while loop, the condition will now be false and so the loop stops. Make sure this loop is in the click listener function of the button. Or in any other function but be sure to call it from the click listener.
Related
first of all, i already tried this: Continuously increase integer value as the button is pressed
But i had 59 errors, yep, 59, and as i used to use Eclipse which told you CLEARLY what kind of error you had, how to fix it, and Android Studio looks that was made for people with experience... I can't even understand what the hell to do, to fix all errors (btw, when i try to fix something i break 10 more somehow).
So... Given a Button and a TextView how do i do to increase the textview (like a Clicker game for example) and make it stop pressing the same button again:
And how do i put the intervals between each "click"
TextView score = (TextView) findViewById(R.id.textView);
score.setText(Integer.toString(i));
Button click = (Button) findViewById(R.id.button2);
click.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
i++;
score.setText(Integer.toString(i));
}
});
By the way... I don't need the solution, i need to understand how exactly Thread or Handlers works, yes everybody will recommend me the Documentation, but i need to see a SIMPLE example explained part by part and i will understand way more than i already do by reading the documentation.
Given a Button and a TextView how do i do to increase the textview (like a Clicker game for example) and make it stop pressing the same button again: And how do i put the intervals between each "click"
Given your score and click widgets from your question:
Step #1: Add a Runnable field to your activity or fragment. Here, I'll call it incrementer.
Step #2: Define a static final int DELAY field in your activity or fragment, with the delay period you want ("intervals") in milliseconds.
Step #3: Have your Button use postDelayed() and removeCallbacks(), based on the state of incrementer:
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
if (incrementer==null) {
incrementer=new Runnable() {
#Override
public void run() {
i++;
score.setText(Integer.toString(i));
v.postDelayed(incrementer, DELAY);
}
};
incrementer.run();
}
else {
v.removeCallbacks(incrementer);
incrementer=null;
}
}
}
The incrementer field serves two roles. It tracks whether we are incrementing the TextView content or not, and it is the actual code that does the incrementing.
If incrementer is null, we are not presently incrementing the TextView. So, we assign incrementer a Runnable that can increment the TextView. The Runnable also calls postDelayed() to say "hey, run this Runnable again after DELAY milliseconds". We run() the Runnable ourselves the first time, to both populate the TextView at the outset and to trigger the postDelayed() call to schedule the next increment.
That will then continue to "loop" (run() calling postDelayed(), scheduling a future call to run()) until the user clicks the button again. Then, we see that incrementer is not null, so we must be incrementing the TextView and need to stop. removeCallbacks() unschedules the last postDelayed() call, stopping the "loop". We set incrementer to null mostly to prepare ourselves for the next button click.
I want to create a condition to wait for a broadcast upon a button press
right now I am just doing solo.sleep(10000)
but I dont want to sleep solo for nothing
How do I formulate the condition "broadcast received" ?
Ok explanations
Robotium Solo is an instrumentation framework with nice api
It has a method called "solo.waitForCondition(Condition, int timeout)"
I want to formulate (the word formulate means say what i want to say in correct words)
the correct condition that will tell me that the broadcast was indeed received
I want to write some code (I don't know which exactly) to know that the broadcast was indeed sent
for example, if i want to know that a button is now visible i would write
solo.waitForCondition(new Condition(){
public boolean isSatisfied(){
Button b = getActivity().findViewById(R.id.myButton);
return b.getVisibility() == View.VISIBLE;
}
}
now back to my question - What (not how, but what) do I write in order to know for sure that the broadcast was sent inside the isSatisfied method
I suppose you meant that you don't want to sleep for 10 seconds, if you get the broadcast earlier. What you can do is
long beginTime = new Date().getTime();
while (new Date().getTime() - beginTime < 10000) {
solo.sleep(500);
if (conditionMet) {
// Do something
break;
}
}
This way you can do these checks on smaller intervals.
Ok, so in fact this is more or less how waitForCondition is implemented. Unfortunately I don't think you can listen for events with robotium. What you can do is monitor the view hierarchy. In your case, there should be some difference to the views that is triggered when the button is clicked, so that is what you need to check for in the Condition (and your example does that).
This is if you don't want to edit the code you are testing. If you are willing to change the code, you can add an onClickListener() and in that you can set a view's Tag to a boolean for example. Later in robotium you can check for that tag for being set. This is however not good way to do it, because you are adding more code just for the sake of the tests.
I want my application can get user's input of time (HH:mm) from EditText widget.
Based on this time value my app needs to show a dialog when current time matches entered time.
Gaauwe
*Edit*
I want to place an EditText widget in my app.
A user will fill it with some time value (e.g. 10:30).
Then when real time (10:30) come up a dialog will be shown.
I think you can use the AlarmManager for this.
I d suggest you have a look at some tutorials like these to help you get started
http://michael.theirwinfamily.net/articles/android/android-creating-alarm-alarmmanager
http://android.arnodenhond.com/tutorials/alarm-notification
That is not too difficult. When user finished editing you EditText, read the time value and create instance of AlarmManager with start time calculated as difference between current time and whatever user wrote in the EditText. Better to use TimePicker to avoid parsing user`s input. Add receiver for you AlarmManager, receiver will start Service which will show dialog or do anything you want. You need to use AlarmManager because if your device is sleeping nothing will wake it up except system call like AlarmManager. #Zortkun 's post with links will help you to figure out how manage AlarmManager.
try this :
use the service : then when user enter time starts a service when system time and user entered time match the shows..
You can pull the data out of the EditText with:
findViewById(R.id.yourEditText).getText().toString();
The rest of your question I didn't understand.
RAW WAY!
So when user put text inside edittext and click button, you could save text in this way:
String time = findViewById(R.id.yourEditText).getText().toString();
and start a thread that check for time, and when time is equal to user's string time, you can show a dialog :)
Thread t = new Thread(new Runnable(){
public void run(){
while(new Date().getLocalTime()!=usersTime){ // is just pseudocode
Dialog.show();
}
}
});
I'll try to understand...
Seeing as you know how to pull the text from an EditText, you'll need an if statement.
Something that compares that time to the current time.
if (editTime == realTime) {
Toast.makeText(getApplicationContext(), "RING RING RING",
Toast.LENGTH_SHORT).show();
}
Use something like this:
Read this to figure out how to get a string of current time.
In Android, I need to start and display multiple CountDownTimers at the same time, on the same screen, one after another. How can I proceed implementing this? Will using threads help?
you can define and array or list for each timer you want to run,
and define a timer that decrements them every second.
https://chat.stackoverflow.com/users/443141
has an example on how to schedule tasks every second. In the method that gets
called every second, decrement the values of all arrays and update a text-label.
...
for ( int i=0; i < timers.length; i++) {
if ( timers[i] > 0 ) {
timers[i]--;
// update your textlabel
} else {
// change the text color, flash,vibrate,...
}
}
...
to reset a timer simply set a new seconds left value.
I am writing an application that searches a database in "realtime".
i.e. as the user presses letters it updates a search results list.
Since the search can take a while, I need to do the search in background and allow new key presses to re-start a search. So that is a user presses 'a' (and the code starts searching for "a"), then presses 'b' - the code will NOT wait for "a" search to end, then start searching for "ab", but rather STOP the "a" search, and start a new "ab" search.
To do that I decided to do the search in an AsyncTask. Is this a wise decision ?
Now - whenever a keypress is detected, I test to see if I have an AsyncTask running. If I do - I signal it (using a boolean within the AsyncTask) it should stop. Then set a timer to re-test the AsyncTask within 10 mSec, to see if it terminated, and start the new search.
Is this a smart method ? Or is there another approach you would take ?
TIA
First yes, AsyncTask is a good way to do this. The problem I see with your approach is the timer waiting to watch something die. When you invoke the asyncTask hold onto a reference of it. Let it keep state for you so you know if it's out searching or it's has returned. When the user clicks another letter you can tell that asyncTask to cancel. Something like this:
public void onClick() {
if( searchTask != null ) {
searchTask.cancel();
}
searchTask = new SearchTask( MyActivity.this ).execute( textInput.getText() );
}
public class SearchTask extends AsyncTask<String,Integer,List<SearchResult>> {
private boolean canceled = false;
protected onPostExecute( List<SearchResult> results ) {
if( !canceled ) {
activity.handleResults( results );
}
}
public void cancel() {
canceled = true;
}
}
This is safe because onPostExecute() is on the UI thread. And cancel() is only called from the UI thread so there is no thread safety issues, and no need to synchronize. You don't have to watch a thread die. Just let the GC handle cleaning up. Once you drop the reference to the AsyncTask it will just get cleaned up. If your AsyncTask blocks that's ok because it only hangs up the background thread, and when the timeout hits it will resume by calling onPostExecute(). This also keeps your resources to a minimum without using a Timer.
Things to consider about this approach. Sending a new request everytime a new letter is typed can overload your servers because the first few letters are going to produce the largest search results. Either limit the number of results you'll return from the server (say 10-50 results max), or wait until they've entered enough characters to keep results down (say 3). The cons of making the user type more characters is the feedback doesn't kick in until 3 chars. However, the pro is it will dramatically reduce the hits on your server.