I have an activity in which i need to implement a basic mm::ss timer . Below is the code i have written for it. However the problem is that when i press the back button in the emulator and click on the app again, the values change much faster. It looks like the onCreate is being called again. How do i rectify this?
I have tried creating a boolean variable and setting it to true the first time the task is invoked . I call the startPeriodidUpdates() only when the value is false.But the onCreate creates the variable again with the value of false.
public class GraphicsActivity extends Activity {
static int seconds = 0;
static int minutes = 0;
public static String time_elapsed;
public static boolean clearView = true;
Handler myhandler = new Handler();
public static String min,sec;
public static boolean running = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startPeriodicUpdates();
}
public void onResume(){
super.onResume();
}
public void onPause() {
super.onPause();
}
public void onStop(){
super.onStop();
}
public void startPeriodicUpdates()
{
periodicCall();
}
public void stopPeriodicUpdates(){
myhandler.removeCallbacksAndMessages(myhandler);
}
public void periodicCall()
{
seconds++;
if(seconds ==60)
{
seconds=0;
minutes++;
if(minutes==60)
{
seconds=0;
minutes=0;
}
}
// left-padding zeros to the minutes and seconds values
min = String.format("%02d",minutes);
sec = String.format("%02d",seconds);
time_elapsed = min + ":" + sec;
time_elapsed = min + ":" + sec + "";
myhandler.postDelayed(new Runnable(){
public void run(){
periodicCall();
}
},1000);
}
Perhaps this will help: The right way to do a peridic task is registering the handler in the OnResume and unregister in in OnPause. (You can unregister it other places, but OnPause is important)
I think its better if you use a Service for implementing your timer. Even if you push back button, the Service will continue running.
Here you can see a question I asked a bit time ago. You can see the implementation of a Custom Chronometer using a Service.
The activity where you want to receive the value of the Chronometer just need to have a BroadcastReceiver like:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
mMilis = intent.getLongExtra("milis",0);
String time = intent.getStringExtra("tiempo");
// Do Something with the time
}
};
This may not be a solution to the problem above, but if you just want to update a view and count up form a given time, maybe have a look at Chronometer. If you want to count down and update views, you can do that with CountDownTimer
You can use shared preference to use this method only once .
//pass true first time
protected void storeSharedPrefs(Boolean value) {
/*
* Storing in Shared Preferences
*/
editor.putString("first", value);
editor.commit(); //Commiting changes
}
Check each on time application is loaded, whether its the first time and configuration details has been entered correctly by checking SharedPreferences
private boolean first_time_check() {
/*
* Checking Shared Preferences if the user had pressed
* */
Boolean first = uPreferences.getString("first", false);
return first;
}
Related
I have a service as MyService. In my service, I have a global variable: value which is controled by a function control_Value(). The function used to control the value of varialbe value as follows rules:
The time when calling the function is called initial time. At intial time, the value is set as One. After 3 seconds from initial time, the value is set to Zero. The value will maintain Zero until the function is called again.
Based on the rule above, I wrote the control_Value() as follows:
public void control_Value()(){
value="One";
try{
Thread.sleep(3000);
value="Zero";
}
catch{}
}
Do you think Thead.sleep(3000) is a good approach? If not, please give me a better solution. Note that, the above function worked well.
This is my service
public class MyService extends Service {
String value=null;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//TODO do something useful
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
#Subscribe
public void onSMSContentReceived(OnSMSReceiverEvent event) {
control_Value();
}
}
Update: The onSMSContentReceived is called automatically when a SMS come to phone.
This is solution using countdown timer from suggestion of TGMCians
//Global variable
private CountDownTimer mCountDownTimer;
//
#Override
protected void onDestroy() {
if(mCountDownTimer!=null){
mCountDownTimer.cancel();
}
super.onDestroy();
}
public void control_Value()(){
mCountDownTimer = new CountDownTimer(3000,1000) {
#Override
public void onTick(long millisUntilFinished) {
value="One";
}
#Override
public void onFinish() {
// Your stuff
value="Zero";
}
};
mCountDownTimer.start();
}
Do you think Thead.sleep(3000) is a good approach?
Never. Service run on application main thread without UI. Application will prompt ANR message in case you hold application main thread for certain seconds.
What to do
If you want to perform operation after certain seconds, then you can use CountDownTimer in your service which has methods onTick & onFinish where onTick hits on regular interval and onFinish hits when time is up.
I want every 1 second registerReceiver.
I try
registerReceiver(receiver, new IntentFilter(Intent.ACTION_TIME_TICK));
but this code every 1 minute
I want every 1 second.
Perhaps, android have a form ?
thanks
What are you trying to accomplish? If you just want to have some code executed every 1s, don't user a BroadcastReceiver. Receivers result in inter-process communication every time they are triggered which is (relatively) expensive.
Best way would be to use a handler,
private static final long TICK_INTERVAL = TimeUnit.SECONDS.toMillis(1);
private static final Handler tickHandler = new Handler(Looper.getMainLooper());
public void onResume() {
super.onResume();
tick(TICK_INTERVAL);
}
private void tick(final long interval) {
tickHandler.postDelayed(
new Runnable() {
public void run() {
tick(interval);
onTick();
}
},
);
}
protected void onTick() {
// do something
}
Ensure you stop the ticking when your activity pauses,
public void onPause() {
super.onPause();
tickHandler.removeCallbacksAndMessages(null);
}
In Java for Android, I want to create a variable that increases by 1 every second, in other words, it counts, that way I can check to see if a function has been called in the past 3 seconds, and if not, I want it to do something different than if it had been.
Is there any built-in way to do this? I'm familiar with the Timer class, but it doesn't seem to work the way I would want it to.. is there anything else?
tl;dr: I want to create a variable that increases by 1 every second, so I can use it to treat a function differently based on how long it has been since its last call. Is there an easy way to do this? If not, what is the hard way to do this?
Why not store the last time the method was called instead, then check it against the current time?
private long timeLastCalled;
public void someMethod() {
timeLastCalled = SystemClock.elapsedRealTime();
}
public boolean someMethodCalledRecently() {
return (SystemClock.elapsedRealTime() - timeLastCalled) > 3000;
}
final int[] yourVariable = new int[1];
yourVariable[0] = 0;
updateVariableTimer = new CountDownTimer(howLongYouWantTimerToLast, 1000) {
#Override
public void onTick(long l) {
yourVariable[0] += 1;
}
}.start();
Or Alternatively to do it with a flag instead of keeping track of variable counting:
final boolean functionCalledRecently = false;
hasFunctionBeenCalledRecentlyTimer = new CountDownTimer(3000, 1000) {
#Override
public void onTick(long l) {
functionCalledRecently = true;
}
#Override
public void onFinish() {
functionCalledRecently = false;
}
}.start();
If you just need to see if the method has been called within the last 3 seconds you can use a Handler and a Boolean flag to acomplish this.
private Handler mHandler = new Handler();
private boolean wasRun = false;
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
if(wasRun){
//whatever you want to do if run
}
mHandler.postDelayed(this, 3000);
}
},3000); //3 sec
In this example the Handler will run on a 3 second delay. Each time it runs it will check to see if the other method was perviously called by evaluating if(wasRun). This way you can change what happens if the method was/was not called. The handler will then start iself again on another 3 second delay. All you have to do then is update the wasRun flag to be true if your method was called, or false if it was not. .
I have an assignment of moving the png file of a signature to one of our servers. The solution I implemented is to have a background service that monitors the folder it is saved in then move it. This works well but the service shuts down after a certain period of time, might be an hour or something, but I'd like it to be persistent. Doing some research resulted in either using a alarm manager or a handler to keep the activity alive.
I decided to use the handler. However whenever the activity is called the device hangs and it takes more memory every time I refresh it. The culprit may be due to not calling 'stopWatching()' though it is possible I handled the problem incorrectly.
SendToPHP.java
public class SendToPHP extends Activity {
final int FIFTEEN_MINUTES_IN_MILLISECONDS = 900000;
//The handler will run the function restart at a later time
//This should prevent the intent service timeout.
Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
finish();
startActivity(getIntent());
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent mServiceIntent = new Intent(SendToPHP.this,
BackgroundService.class);
// Starts the IntentService
SendToPHP.this.startService(mServiceIntent);
handler.postDelayed(runnable, FIFTEEN_MINUTES_IN_MILLISECONDS);
}
}
BackgroundService.java
#Override
protected void onHandleIntent(Intent workIntent) {
/************* Php script path ****************/
upLoadServerUri = "*redacted*";
//FileObserver monitors files/directories, in this case we want any file that is
//created in SignItPictures
FileObserver observer = new FileObserver(android.os.Environment
.getExternalStorageDirectory().toString() + "/Pictures/SignItPictures", FileObserver.CREATE ) {
#Override
public void onEvent(int event, String file) {
uploadFileName = file;
uploadFile(uploadFilePath + "/" + uploadFileName);
}
};
observer.startWatching(); // start the observer
}
Try adding START_STICKY in the onStartCommand method of your Service class
In my activity oncreate method, i have called a service using OnStartCommand(). My requirement is when the user is on the same Activity (when the Activity is visible), a set of code should run repeatedly. (Example .. I should make a web service call and get the response and do some action based on it after regular intervals).
I have put this set of code in this method.
#Override
public int onStartCommand(Intent i, int flags , int startId){
// Code to be repeated
return Service.START_STICKY;
}
But, this is getting executed only once. How to make it run repeatedly from the time the user came to this page till he leaves this page ??
CountDownTimer.cancel() method seems to be not working.
I would recommend you to use Timer instead. It's much more flexible and can be cancelled at any time. It may be something like that:
public class MainActivity extends Activity {
TextView mTextField;
long elapsed;
final static long INTERVAL=1000;
final static long TIMEOUT=5000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextField=(TextView)findViewById(R.id.textview1);
TimerTask task=new TimerTask(){
#Override
public void run() {
elapsed+=INTERVAL;
if(elapsed>=TIMEOUT){
this.cancel();
displayText("finished");
return;
}
//if(some other conditions)
// this.cancel();
displayText("seconds elapsed: " + elapsed / 1000);
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, INTERVAL, INTERVAL);
}
private void displayText(final String text){
this.runOnUiThread(new Runnable(){
#Override
public void run() {
mTextField.setText(text);
}});
}
}
You can use Timer for the fixed-period execution of a method.
See here is a tutorial on this:
http://steve.odyfamily.com/?p=12