i need a countDownTimer keep running when i swap between activities.. i have more than one activity, i put the countDownTimer in the main activity but when i swap to another activity and back to the main activity it turns back to count again from the start, i believe because the method countDownTimer is onCreate method.
So, how should I go about doing this?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
questionTime();
}
public void updateTimer(int secondsLeft){
int minutes = (int) secondsLeft / 60;
int seconds = secondsLeft - minutes * 60;
String secondString = Integer.toString(seconds);
timerTextView.setText(Integer.toString(minutes) + ":" + secondString);
}
private void questionTime(){
new CountDownTimer(10000, 1000){
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
timerTextView.setText("0:00");
Log.i("finished", "timer Done");
}
}.start();
}
Update: That helped me to reach my purpose How to run CountDownTimer in a Service in Android?
Maybe this is a little far fetched, but the way that I think to solve this issue and not worrying for the Activities is using an IntentService.
Even if you store some sort of value in the Bundle of the onSaveInstance() hook method this can lead to some pretty messy results if you enable the "Don't keep activities" flag in the device's settings.
What I would do is create an IntentService that when It's triggered starts the countdown, then It broadcast the changes of that countdown through EventBus/Otto/BroadcastReceiver back to the UI.
Another way of doing it is having the countdown instance in your Application class, and check it from there.
I would go with the IntentService solution because having a countdown instance running in the Application class sounds a little off.
Let me know if you want any specifics on how to implement the IntentService but a little bit of Googling should show you how to do it.
As soon as the time starts, write the time (unix timestamp) to properties file. And when the user comes back to your main activity, read the properties file and compare it the time in the properties file with current timestamp and update the timer based on that.
Related
I am just starting to learn Android, Java and need help.
I have an activity with the countdowntimer, which works fine. However, I want it to be displayed in the fragment. What is the best way to do it?
I tried calling Timer.getCountdowntimer, I tried calling Timer.getUserTime (userTime is the user selected time for the countdowntimer), but the textview in my fragment doesn't display the timer.
thanks in advance!
If you are coding in Java purely, and want to use the android SDK to do it, I would recommend:-
//Create a handler that runs on main loop so we can update UX
final android.os.Handler handler = new android.os.Handler(Looper.getMainLooper());
//Get a callback in 1 second
handler.postDelayed(new Runnable() {
int timer;
#Override
public void run() {
timer += 1;
myTextView.setText(String.valueOf(timer));
//Recursively get another callback in a second
handler.postDelayed(this, 1000);
}
}, 1000);
Make sure you add some logic to stop the timer when you want, and also onPause/onResume
I am making an Android app that has a time limit to the amount of points you can get. But if you close the app, the timer keeps going. How do I pause the CountDownTimer when the app pauses?
You can cancel it in onPause() with something like
#Override
public void onPause()
{
super.onPause();
timer.cancel(); // timer is a reference to my inner CountDownTimer class
timer = null;
}
And use the millisUntilFinished variable to save in a SharedPreference or some other persistent variable. Then use that variable again to start the timer in onResume()
Shared Prefs
This answer may be helpful if you need to pass the value to another Activity.
I want the functionality of Google Now app, like when it's day time, the header is a sunny image, when it becomes noon or sundown, the image changes to a sundown image, when it's night the image changes to a night image, and same for the morning one.
I'm trying to implement my background which does this very same thing, how must I go about implementing this? I've searched up on this but the answers are for html and website development.
And most of the others are based on time interval and I think that's what I should use but I would like something like this. Written in non-tech language
01:00/1am - Morning - Image changes to Morning.png on the imageview (R.id.view).
09:00/9am - Normal - Image changes to Daytime.png on the imageview (R.id.view).
12:00/12pm - Noon - Image changes to Noon.png on the imageview (R.id.view).
19:00/7pm - Night - Image changes to Noon.png on the imageview (R.id.view).
How I can achieve something similar to this?
Well the best candidate for this job is an AlarmManager!
Lets assume you only need to change the background when your Activity is running.
You can set up your alarm when you Create your Activity:
private PendingIntent pi=null;
private AlarmManager mgr=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mgr=(AlarmManager)getSystemService(ALARM_SERVICE);
pi=createPendingResult(ALARM_ID, new Intent(), 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + PERIOD, PERIOD, pi);
}
PERIOD (ms) is how often we want to get control (onActivityResult). The createPendingResult(ALARM_ID, new Intent(), 0); line creates an Intent that can be caught in your Activities onActivityResult method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ALARM_ID) {
// This is where you check the time and change your background!
}
}
You also need to cancel your alarm in onDestroy:
#Override
public void onDestroy() {
mgr.cancel(pi);
super.onDestroy();
}
To check if a Date is in a specific interval you can use:
boolean isWithinRange(Date testDate) {
return testDate.getTime() >= startDate.getTime() &&
testDate.getTime() <= endDate.getTime();
}
I advice you write a class which has a listen method. This listen method which checks time and raises a custom event (you can use interface here) on Activity level must be called periodically. You can use Timer and TimerTask or CountdownTimer to call.
I am using
<Chronometer android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/chrono"
android:visibility="gone" />
in my one activity now my question is can I make it global for all of my activities so that I can show its value to every activity in my android app?
If yes then how to do this please give example because I am new in android??
Here is my timer code
Chronometer stopWatch;
stopWatch.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener(){
#Override
public void onChronometerTick(Chronometer arg0) {
countUp = (SystemClock.elapsedRealtime() - arg0.getBase()) / 1000;
long min = countUp / 60;
long sec = countUp % 60;
String minStr = "";
String secStr="";
if(min < 10)
{
minStr = "0"+min;
}
else
{
minStr = ""+min;
}
if(sec<10)
{
secStr = "0"+sec;
}
else
{
secStr = ""+sec;
}
// String asText = (countUp / 60) + ":" + (countUp % 60);
String asText = minStr + ":" + secStr;
textGoesHere.setText(asText);
}
});
stopWatch.start();
Here is an idea. Create a separate layout for your Chronometer and <include /> it in all the layouts that require a Chronometer.
Now you can either use a Singleton pattern or SharedPreferences to store the attributes such as start time, current state (Paused, Running, Stopped, Reset) of your timer. Whenever you start a new activity get the state of the timer and show it on your Timer.
For instance if the current state is running then you may have to kick start a thread to update the timer or if the timer is stopped just get the start time and stop time from your SharedPreference or your Singleton class and show it on the timer.
For instance, consider the following scenario. For simplicity let's have 2 Activities, ActivityA and ActivityB.
Now here are some of the states for your timer, yours could be different.
Ready (00:00 - Your timer is ready to run)
Running (Timer is running)
Paused (Timer is paused and can be resumed)
Stopped (You have stopped the timer and it displays the elapsed time and the next possible state would be 1 i.e, ready.)
You would need several other parameters such as,
Timer start time (System.currentTimeInMillis() minus this time gets you elapsed)
Timer stop time (Used to calculate timer paused and stopped time)
Let's consider this case. You are starting a timer from ActivityA and want to retain the state on ActivityB. Here are the set of things you might want to do.
When you start your timer by any event - say click of a button, you have to save the start time in your SharedPreference.
Now you want to navigate to ActivityB, then you have to save the timer state to your SharedPreference in the onStop() method of your ActivityA.
Now after you start ActivityB, in the onResume() method get the start time from the SharedPreference, the System.currentTimeInMillis() minus the start time will give you the elapsed time. Next, you have to get the timer state from your SharedPreference.
If the state is running, then you have to start a thread to update the timer. If the timer is stopped, then it's enough to show the time elapsed on your timer.
This is the outline of the solution. You can learn about SharedPreferences from here.
Also, you need to be familiar with the Activity lifecycle, which you can learn from here.
No, you can't.
Activities have a life cycle in Android : they are created, started, display & do stuff, get stopped and destroyed. And all the views inside obey to this life cycle.
Don't fight against it, that's the way Android is and it's great like that, learn this life cycle.
The views of an activity don't exist outside of it. This would have no meaning. You should read on how to pass information from one activity to another.
Also, maybe your question is : how can all my activities have the same view in their layout, each one having its own instance of the view. In that case, use the include xml keyword.
yes you can do this but not by making it global. it is little tricky.
what you have to do is:
- make choronometer xml declarartion with tag in each Activity.
- make access of this chronometer in base class.
Just like an example: i required header in each of activity but i wanted to do coding only at one place. so what i do is:
/**
* Method to init Header components sets header bar title and header bar
* buttons. This method sets onClickListener to
*/
private void initHeader() throws InvalidHeaderTitleException {
try {
View headerView = findViewById(R.id.header_layout);
if (headerView != null) {
headerTextView = (TextView) headerView
.findViewById(R.id.layout_header_textview_header);
nextHeaderButton = (Button) headerView
.findViewById(R.id.layout_header_button_next);
prevHeaderButton = (Button) headerView
.findViewById(R.id.layout_header_button_previous);
if (headerTextView != null) {
String title = getHeaderText();
if (isValidString(title)) {
if (title.length() > IDryIceUIConstants.LENGTH_HEADER_TEXT)
title = title.substring(0,
IDryIceUIConstants.LENGTH_HEADER_TEXT)
+ IDryIceUIConstants.SUFFIX_HEADER_TEXT;
headerTextView.setText(title);
} else {
throw new InvalidHeaderTitleException(title);
}
}
if (nextHeaderButton != null) {
nextHeaderButton.setVisibility(getVisibility());
nextHeaderButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
headerNextButtonClicked();
}
});
}
if (prevHeaderButton != null) {
prevHeaderButton.setVisibility(getVisibility());
prevHeaderButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
headerPrevButtonClicked();
}
});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
xml declaration in each Activity xml is
<include
android:id="#+id/header_layout"
android:layout_width="fill_parent"
android:layout_height="40dip"
layout="#layout/layout_header" />
Here is my code,
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
forgotpass.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
forgotpass.setText("done!");
}
}.start();
I want it to continue to run even after my activity or application closes.
So far when i press the back button or the home button on the application it is running on it stops automatically and when i reopen the activity it starts back on 30. Is there any possible way I can have it continue to countdown even when the application or the activity is not running?
There is no possible way you can achieve that unless you do it in a Service.
Start it as service. Bind the service in the onDestroy()