I am working on a game (my first) for Android. I want a function like a lot of games do where a "consumable" regenerates over time. I want to display the countdown timer for a +1 on the consumable. When it reaches 0, i want the timer to reset and start over, while the consumable increases by 1. If the consumable is at it's pre-defined max, I want the timer to stop until the consumable is used, then systematically start again.
public class MainActivity extends Activity {
int currentConsumable = 2;
int maxConsumable = 5;
boolean isConsumableMaxed = false;
long timeToAddConsumable; //unknown calculation for 10 minutes
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView countDown = (TextView) findViewById(R.id.countDownDisplay);
if (currentConsumable==maxConsumable) {
isConsumableMaxed = true;
//some function to stop the timer
} else { isConsumableMaxed = false; }
//function to begin countdown and setText to countDown's TextView
....
}
}
What I am looking for assistance with is how to calculate the time I need (10 minutes - but i'd prefer the equation so I can change it without asking for the specific time again).
I would also like to know how to get a countdown to begin and display it on countDown, as well as how to cancel it when isConsumableMaxed == true.
Note - the countdown should continue when the game is closed.
Thanks in advance for your assistance.
Related
I am trying to write an app that shows the user a string on textview, and replace the text due to user input. This should happen on time intervals of 60 seconds.
I tried to use a countdown timer, which sets a boolean var to false on it's onFinish method. While this boolean is true, I am trying to change the strings in the textview (further work will be to change the text due to the user actions, but I'm still trying to get this work for simple actions).
For now, the app seems to be stucked and nothing happens, but if I am removing the while loop, there is a single text on the screen (as it should be).
Is there a problem using a while loop for that purpose? Is there a different way to work along with the timer?
(p.s I know there are some problems in the code, but this is just for isolating the problem. Thanks!)
EDIT:
I will try to clarify my intentions:
I want to give the user tasks, which he should perform in a given time. I want to display the time remaining on the screen, along with the task to perform. When the user finishes the task, if there is still time on the clock, he will press a button and another task will appear. The goal is to finish as many tasks as possible in the given time.
My code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start_game);
Bundle b = getIntent().getExtras();
game = b.getParcelable("game_record");
figuresList = new ArrayList<String>(game.getFiguresList());
clockView = (TextView) findViewById(R.id.clockView);
figureText = (TextView) findViewById(R.id.figureText);
timer = new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
clockView.setText(Long.toString(millisUntilFinished / 1000));
}
public void onFinish() {
clockView.setText("done!");
isTurn = false;
}
};
playRound();
}
private void playRound() {
figuresIterator = figuresListUsage.iterator();
isTurn = true;
String nextFigure = figuresIterator.next();
timer.start();
while (isTurn == true) {
figureText.setText(nextFigure);
nextFigure = figuresIterator.next();
}
}
It's a little difficult to understand your games logic but the main problem i see with your code is that you are entering the loop in a lifecycle event handler. Take a look at this lifecycle description. You are stopping it in onCreate and there is still work to be done before the activity will finish its lifecycle handling.
I suggest you try making play round event bound or use a diffrent thread for it. there are alot of threading APIs for android and as i dont know the nature of your game rounds i cant recommend any.
I'm making an application and a certain part in my application I store a list of prices along with the time that the prices last for (they do not all last the same amount of time). So a price lasts a certain time then once that price's time is up it changes to another price (this part changes the UI or basically it updates a textview with the new price). So what I need is a timer that sets the timer again with the new time length and once it's done make the UI change. For instance say that each of the pairs represent the price amount and the time (in seconds): { {$2.53,1.4s}, {$4.57,4.45s}, {$1.23,3.6s}...}
So when the timer starts off the textview displays $2.53 and the timer lasts 1.4s and then it should grab the next price $4.57 and be set again but this time for 4.45s. This process continues on and on until the game is finished. I was thinking of using the CountDownTimer and resetting itself once the onFinish() method is called (I haven't verified if this idea works yet). Are there any other ideas?
You can use a countdown timer and onFinish method you call back the function and it starts another timer:
private void startWheatPrices(long gameTime)
{
//other stuff executed
StartWheatTimer(GameTimeDifference);//starts the timer for the first time
}
private void StartWheatTimer(long TimerAmount)
{
WheatTimer = new CountDownTimer(TimerAmount, 10) {
public void onTick(long millisUntilFinished)
{
}
public void onFinish()
{
//other stuff executed
WheatPricesTV.setText(Float.toString(PriceList.get(0).get(WheatPriceIndex).price));//price is changed
if(InGameplayMode)
StartWheatTimer(convertToMilliseconds(PriceList.get(0).get(WheatPriceIndex).timeLength));//call back the function to start the timer again
}
}.start();
}
i have a simple Application about writing the sentence which is shown when the application starts.The only Problem is, i need the application to calculate the time it took the user to write the sentence .. like when you touch "Submit" Button , the Toast message will say " Thats Right ! , It took you 3.2 Second" As Example .
I heard you can set a timer to start on when specific action occurs ... and you can order it to stop .
So let's say The Timer will start when you start the app and it will stop when you touch "Submit" button , and give a toast message like above calculating the exact time it took you to write the sentience after starting the App ! *
Here is the App Code hope it helps : *
Button w;
TextView t;
EditText e;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
w = (Button) findViewById(R.id.Write);
t= (TextView) findViewById(R.id.FTS);
e = (EditText) findViewById(R.id.Text);
w.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String check1 = t.getText().toString();
String check2 = e.getText().toString();
if (check1.equals(check2))
Toast.makeText(MainActivity.this,"You Wrote it Right !!!",Toast.LENGTH_LONG).show();
else if (check2.equals(""))
Toast.makeText(MainActivity.this,"It's Empty",Toast.LENGTH_LONG).show();
else
Toast.makeText(MainActivity.this,"You wrote it wrong,try again !",Toast.LENGTH_LONG);
I'm Totally new to Android so I really don't know how to do it , Thanks for your Time .*
you can use the Timer class to start a timer session. Follow the steps:
1- define a global variable of the Timer and a variable to count the time like:
private Timer t;
private int TimeCounter = 0;
2- then when the activity starts, so in onCreate add the following: P.S: what I did is I have a textView to show the timing while he is writing the sentence. so if you dont want that you can delete the tvTimer part in the following code
t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText(String.valueOf(TimeCounter)); // you can set it to a textView to show it to the user to see the time passing while he is writing.
TimeCounter++;
}
});
}
}, 1000, 1000); // 1000 means start from 1 sec, and the second 1000 is do the loop each 1 sec.
then when the button is clicked, stop the timing and show the timeCounter varaible in the Toast.
t.cancel();//stopping the timer when ready to stop.
Toast.makeText(this, "The time taken is "+ String.valueOf(TimeCounter), Toast.LENGTH_LONG).show();
P.S: You have to deal with converting the seconds into minutes because the number could extends to 360 secs so you need to convert it to 6 minutes. you can do it in the t.schedualeAtFixedRate or after you done you can convert it and show it in the toast
hope you found this useful. please give me a feedback if it worked for you.
Let me direct your attention to the Chronometer Widget on the Dev Page
Also here's a flavor of what you will get by using the Chronometer Widget (skip to 8:30)
Video of Chronometer Widget
XML
<Chronometer
android:id="#+id/chronometer1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Java
((Chronometer) findViewById(R.id.chronometer1)).start();
((Chronometer) findViewById(R.id.chronometer1)).stop();
I have an activity that runs some ASCII control over a network port to a remote device.
Every single button push on the interface will trigger an AsyncTask to handle the communication, and (finally) works great.
However, if a user starts button mashing like a chimp on crack, the system will crash with way too many calls on the same socket, so I've come up with a little timer function to slow down the reaction to their excitement.
I'm wondering if somebody has come up with a better way to do this?
First off, inside the onCreate:
btn_pwrtoggle = (Button)findViewById(R.id.pwr_btn);
btn_pwrtoggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!buttonMasher){
if(powerstat.equals("OFF")){
String[] commandToSend = {"POWER","ON"}
}else{
String[] commandToSend = {"POWER","OFF"};
}
deviceControl(commandToSend);
}
startButtonMashTimer();
}else{
Log.w("button masher","slow down there, monkey.");
}
}
});
Then, in the actual Activity:
Timer buttonTimer;
TimerTask buttonMonitorThread;
int chimpCrackCounter;
protected void startButtonMashTimer() {
chimpCrackCounter = 0;
buttonTimer = new Timer();
buttonMonitorThread = new TimerTask(){
#Override
public void run(){
buttonMasher = true;
if(chimpCrackCounter == 1){
buttonMasher = false;
buttonTimer.cancel();
}
chimpCrackCounter++;
}
};
buttonTimer.schedule(buttonMonitorThread, 0, 500);
}
It seems to be working just fine, (and may help somebody having the same difficulty) but I'm open to suggestions.
An easy way to prevent a user from pushing a button too often is to save the time when a button was pushed, and then next time compare the last time with the current time and if the difference is too small, ignore the action.
final static long minTimeBetweenClicks = 1000;
long lastTime;
onClick(View v){
if( System.currentTimeMillis() < lastTime + minTimeBetweenClicks ) return;
//Handle the click
lastTime = System.currentTimeMillis();
}
The beauty of this is that it doesn't require any new threads or timers, and your AsyncTasks won't have to know about the buttons.
Disable the Button after a click (setEnabled(false), perhaps in onPreExecute, and enable after the task is done, in onPostExecute.
Also, be sure to pay attention to lifecycle changes. Your AsyncTask may be killed if the Activity is paused, so be sure to check the state in onResume.
After many trials of solutions (including posting questions on SO) I thouht will work fine. But no improvement. Coming to my problem, I am implementing an App that have a countdown timer. I am showing this on a button (Just using like a canvas by disabling the click event).
I start the timer when user clicks a button (which is a separate button). Below is the countdown timer code,
public class DigitalTimer extends Button{
--------------------------------
--------------------------------
--------------------------------
--------------------------------
--------------------------------
--------------------------------
private String timerText;
public DigitalTimer (Context context,int hourstime,int mintime,int sectime){
super(context);
Log.d(TAG,"DigiTimer constructor");
this.context = context;
initialize(hourstime,mintime,sectime,timerType);
setClickable(false);
}
public void initialize(int hourstime,int mintime,int sectime,int timerType){
Log.d(TAG,"DigiTimer initialize");
this.hourstime = hourstime;
this.mintime = mintime;
hour = hourstime;
min = mintime;
sec = sectime;
//Just Thread version
**digiThread = new Thread(){
#Override
public void run(){
while(!isPauseTimer()){
updateTimes();
SystemClock.sleep(UPDATEDELAY);
}
}
};**
//Handler version
/*
handleRunnable = new Runnable(){
public void run(){
updateTimes();
}
};
*/
}
private void updateTimes(){
timerText = String.format(timerFormat,hour,min,sec );
postInvalidate();
sec--;
if(sec < 0){
sec = 59;
min--;
}
if(min < 0){
min = 59;
hour--;
}
if(hour < 0){ //when hour is negative it means the given time completed so we stop the timer & alarm permanantely
hour = 0;
min = 0;
sec = 0;
}
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Log.d(TAG,"DigiTimer onDraw");
setBackgroundResource(R.drawable.button9patch);
setText(timerText);
}
public void startUpdateTheread(){
//digiHandler.postDelayed(handleRunnable, UPDATEDELAY);
**digiThread.start();**
}
private void startTimersAndAlarms(){
-----------------------
-----------------------
-----------------------
-----------------------
**startUpdateTheread();**
---------------------
---------------------
}
}
Initially the timer is woking fine . But if no.of hours for the countdown is higher (say 5:00:00) then its running fine until sometime (say 4:00:00) from then it is delaying the timer update. (just to countdown a minute it is taking more time ..particularly when the user is out of the App)
First I tried with the Handler. I had the problem. I thought the delay is because of keeping the UI thread busy. So I developed a separate thread. But still the problem persist.
Sorry for the long post. Please someone point what's happening. Is that something I am missing or putting the code in wrong place?
Thanks
EDIT: I read SystemClock.sleep documentation. It says "{This clock stops when the system enters deep sleep (CPU off, display dark, device waiting for external input) }". I understand that I should keep CPU on while I run this thread. So according to the answer by #Brandon I should implement partial POWERLOCK to keep the CPU on. Is my understanding correct?
If you want to have an accurate timer, I think you'll need to get a wake lock.
Check out the documentation of PowerManager
You can either get a FULL_WAKE_LOCK to keep the screen on, or a PARTIAL_WAKE_LOCK to keep the CPU running. Don't forget to add the permission to your AndroidManifest file too.