The aim of my current application is to get current time of my phone , compare it to a list of timerange that i've set and view the time remaining between my current time and the time range ( so I will need a refresh of the view each seconds ).
Example : Current time = 11 pm
Time range A = 11:10 pm
I would like to view :
x = 11h
A = 11h10min
view ( x); // refreshing each seconds
view ( A- x); // refreshing each seconds
For the moment I suceeded to view my current time with :
public class HoraireTempsReel extends Activity {
private TextView tvDisplayTime;
private int hour;
private int minute;
private String CurTime;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.horairetempsreel);
setCurrentTimeOnView();
}
// display current time
public void setCurrentTimeOnView() {
tvDisplayTime = (TextView) findViewById(R.id.tvTime);
final Calendar c = Calendar.getInstance();
hour = c.get(Calendar.HOUR_OF_DAY);
minute = c.get(Calendar.MINUTE);
// set current time into textview
Resources CurTimeRes = getResources();
CurTime = CurTimeRes.getString(R.string.CurTime,hour,minute);
tvDisplayTime.setText(CurTime);
}
}
But I didn't suceed to get it refreshed every seconds.
I've done some researchs and i find out that using handlers may be a solution but the concept is a little bit hard to understand ( i'm a beginner in android dev ) so i would like to know if there is another way to resolve my problem.
( Sorry for my bad english , i'm not a native )
Update :
Thanks for you answer Salauyou !
First, it is a bad style to keep date-time variables in ints or
strings. There is specialized class in Java called Date for this
purpose.
Ok I will try to change as soon as possible .
And don't rely on default locale!
What do you mean ?
Now your timer is scheduled and will execute your
setCurrentTimeOnView() method every 1 second until you cancel it by
timer.cancel()
Ok i tried to adapt the code you give me to my program , it gives something like :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.horairetempsreel);
Timer timer = new Timer();
timer.schedule(new TimerTask(){ // set a TimerTask
#Override
public void run(){ // override its run() method
setCurrentTimeOnView();
}
}, 0, 1000);
}
I don't know where to put the timer.cancel() and it gives me an error on logcat :
E/AndroidRuntime(7701): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Related
i try to schedule 2 tasks, the first need to done everyday - to check birthdays,
the second task need to be only if today is the first day of the month..
i tried to make 1 schedule that will done everyday at 8:00 am , and when its done to check if its the first day of month.
if its true make the method of the second task.
my problem is that the method starts every time that onCreate() done & its the first day t the month, so if i open the app 10 times at the 1/10/16 , the method will happen 10 times, instead of 1 time.
my code:
onCreate()
startTimers();
startTimers method:
private void startTimers() {
d = new Date();
d.setTime(System.currentTimeMillis());
d.setHours(8);
d.setMinutes(0);
d.setSeconds(0);
timer = new Timer();
timerTask = new TimerTask() {
#Override
public void run() {
if(d.getDate() == 1){
// TODO: 19/10/2016 find good if that will make it work only 1 time per month..
saveSalariesBeforeStartNewMonth();
resetSumOfMinutes();
Log.d("TAG","Started new Month good luck!##!#");
}
checkBirthdays();
}
};
timer.schedule(timerTask,d.getTime(),1000*60*60*24);//every day at 8:00 at morining..
}
Thank for helpers.
Try to store a simple boolean to the SharedPreferences after successfully scheduling so that before you call startTimers() just check with the stored value. Sth like:
public void onCreate(){
if (!isScheduledAlready()) {
startTimers();
}
}
public boolean isScheduledAlready(){
SharedPreferences prefs = getPrefs().getPreferences();
return prefs.getBoolean("schedule_keys", false);
}
public void setSchedule(boolean scheduled) {
SharedPreferences prefs = getPrefs().getPreferences();
prefs.edit().putBoolean("schedule_keys", scheduled).apply();
}
Also I'm not sure if in your situation you might want to tweak the value when the month change? If then you can just need add more a bit more conditions I guess.
I am trying to implement a view with a text view counting down a number every 600 miliseconds and dynamically displaying the number in text view.
The problem: the activity gets called as expected, but during countdown the activity gets created again and the countdown begins from the start. The OnCreate() method in my activity gets called twice although it should be called once. I know it could be triggered by a change in screen orientation and other configuration changes, but it doesn't seem to happen here.
OnCreate() in my activity:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.SqueezeLayout);
countdownTextView = (TextView)FindViewById(Resource.Id.countdown_text_view);
Timer myTimer = new Timer(18000, 600, this);
myTimer.Start();
}
My implementation of CountDownTimer:
class Timer : CountDownTimer
{
public int count = 30;
SqueezeActivity squeezeActivity;
public Timer(long totaltime, long interval, SqueezeActivity activity)
: base(totaltime, interval)
{
squeezeActivity = activity;
}
public override void OnTick(long millisUntilFinished)
{
count--;
String countStr = count.ToString();
squeezeActivity.countdownTextView.Text = countStr;
}
public override void OnFinish()
{
squeezeActivity.StartActivity(typeof(AnotherActivity));
}
}
I am a beginner in Xamarin development so please be forgiving :) Thanks.
As it turned out, the method called twice was caused by a simple mistake in code logic - I was calling StartActivity twice. So it had nothing to do with the countdown timer. Thanks for the answers. :)
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.
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'm trying to port a PC Java program to the Android platform. The PC application uses a Swing.Timer to trigger an update every second. The associated listener, upon being called, gets new data from a database, then updates/redraws the screen using Graphics2D. I've learned how to use Android's Canvas to draw the same things that I do with the PC application. Now I'm trying to learn how to use the equivalent Timer in Android. Unfortunately things don't seem as straightforward on the Android platform. There are Timers, Handlers, AlarmManagers, and AsyncTasks. It would seem that AsyncTasks and AlarmManagers are more appropriate for one time (heavy duty?) tasks (right? wrong?) With regard to Timers and Handlers, I've seen many posts that say don't use Timer, use Handlers instead. I found the approach used in the code below somewhere out there on the web and tried it. It seems like it should do what I want but it hangs the GUI whenever I click the stop button. Does anyone know why it does that?
Thanks times a million
Bill
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dateFormat = new SimpleDateFormat(dateFormatString);
mHandler = new Handler();
mUpdateTimeTask = new MyRunnable();
Button button = (Button) findViewById(R.id.start_button);
button.setOnClickListener(new MyStartListener());
button = (Button) findViewById(R.id.stop_button);
button.setOnClickListener(new MyStopListener());
}
class MyStartListener implements View.OnClickListener {
public void onClick(View v) {
if (startUptimeMillis == 0L) {
startUptimeMillis = SystemClock.uptimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
}
}
};
class MyStopListener implements View.OnClickListener {
public void onClick(View v) {
mHandler.removeCallbacks(mUpdateTimeTask);
}
};
class MyRunnable implements Runnable {
public void run() {
final long start = startUptimeMillis;
long millis = SystemClock.uptimeMillis() - start;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
TextView tv = (TextView) findViewById(R.id.time_textView);
tv.setText(dateFormat.format(calendar.getTime()));
mHandler.postAtTime(this, (((minutes * 60) + seconds + 1) * 1000));
}
};
EDIT:
The problem is that postAtTime needs an absolute time at which to start, not a delay which is what my example is using. (See postAtTime here)
So I replaced all of the timing code above with the below and it does what I want!!:
long millis = SystemClock.uptimeMillis();
mHandler.postAtTime(this, millis+1000);
I don't see how this could hang your app, unless you mean the start button doesn't work any more... Perhaps you want to add this to your stop listener:
public void onClick(View v) {
startUptimeMillis = 0l; // Reset startUptimeMillis
mHandler.removeCallbacks(mUpdateTimeTask);
}
As far as Timers, AsyncsTask, etc... You are correct, the best way to program an event in the near future in Android is with a Handler and Runnable. AlarmManagers are not intended for fast callbacks like in animations and AsyncTasks are better for heavy duty computation.
I would like a to offer a simpler update Runnable:
class MyRunnable implements Runnable {
public void run() {
// You should make this a class variable and initialize it in onCreate(),
// there is no need to search for the same View every second.
TextView tv = (TextView) findViewById(R.id.time_textView);
final long now = System.currentTimeMillis();
tv.setText(dateFormat.format(now));
mHandler.postAtTime(this, 1000 - (now - start) % 1000); // Accounts for millisecond offsets over time
// mHandler.postDelayed(this, 1000); // Effected by minute offsets
}
};