I am making an Android application using Flash CC and Air for Android. The application will run continuously (part of the time in the background) on multiple devices and will need to keep asking a server about a certain operation and receiving a yes/no answer.
What would be the best approach to do this? If I use a Timer, it seems to have "up to a maximum of 24.86 days" limitation.
Also, what would be a good approach not to waste too much of the battery as the application will continuously run in the background, never turned off.
The limitation on the Timer class is due to the maximum value of an signed, 32-bit integer. Timer stores its current value as an int, in ms since the start. 24.86 days in ms happens to be 2147904000, or close to the max value of a signed, 32-bit integer (2147483647). The difference between the two is likely made up due to rounding in the true max value of the Timer class.
Anyway, your best bet is to reset the timer every single time. So:
var t:Timer = new Timer( delay, 1 );
t.addEventListener( TimerEvent.TIMER_COMPLETE, timerCompleteHandler );
t.start();
function timerCompleteHandler( e:TimerEvent ):void {
// do stuff here
t.reset(); // resets timer to 0
t.start(); // restarts timer
}
In terms of battery usage, that is a tricky question. I've never dealt with an app always running in the background before. I would definitely avoid having it do anything resource intensive. So things like changing any element of the GUI should be off-limits if the app is inactive/running in the background. Really, we need to know more about what you want to do in the background to determine how to help here. From what you have described here, it almost seems like you would be better off setting up push notifications than using a custom call to your server.
Related
I have a widget/app that performs display [draw...()] operations up to 20 times a second (e.g. animation), depending upon user-selected criteria. When running as a widget, the "full" app is invoked when the widget is touched. (The full app performs similar display operations but has more bells and whistles than the widget.) I want to use the same timing mechanism for both the widget and the "full" app but haven't figured out how to manage this.
Widgets seem to rely on AlarmManager, which does not provide sufficiently accurate timing for my purposes, though it's at least tolerable when running as a widget. Before turning the app into a widget, I used a combination of a Timer and a Handler and this seemed to work OK.
timerHandler = new Handler();
timer = new Timer(timerHandler, drawAction);
Any thoughts on how I might accomplish my goal (assuming it's possible) would be greatly appreciated.
I'm going to agree with CommonsWare here- a widget should not be updating that frequently, widgets should be infrequently updating summaries. Once a second is ok if you're a clock. Anything else should be every few seconds or few minutes.
ANyway, timers and handlers are a pretty old school way of doing animations. Choreographer would be the correct way of getting a regular callback, every 1 60th of a second. Even better, use the Android Animator and Interpolator objects to get regular updates and call setAnimation on your view, avoiding any cheduling of your own.
In what way that I can have a real-time timer for task scheduling on Android?
Currently I am using Java.util.timer for my real-time application? However, the timer is missing firing when garbage collection is running or other other stuff. The description on java.util.timer says "this class does not offer guarantees about the real-time nature of task scheduling.". Then, which class that I should use on Android then? Or are there any other approach to have a real-time guarantee timer on Android?
Forgot to mention that the timer that I need is at 20 - 40 milliseconds precision level. That means, I need it to fire every 20 - 40 milliseconds.
Handler.postDelayed(Runnable r, long delayMillis);
Does not have a note about whether or not it guarantees it to happen on time. I've used this mechanism before and never noticed any inconsistency with it. However, i've only used it for relatively short intervals (less than a minute) If you are looking for something farther out than that I would suggest you take a look at the AlarmClock application in the Android source. That will probably give you a good approach. That being said if you are looking for extreme precision(down to seconds or farther) I doubt you're going to be able to find anything with guarantees. There are too many things that could be going on that could cause potential misfires.
in numerous places, it is mentioned that app widgets should not get updated often, to minimize power consumption.
But, let's consider that an application is doing something important (such as audio recording) for a short period of time, say 30min.
In this case, is it acceptable to update the widget every second from a service?
How can it be that this would consume so much power?
Please consider that this is different from a widget which would update very often during the whole day.
And in my case, such frequent updates would be meant to allow the user to monitor that the operation is being performed continuously and correctly. It's not for fancy visual effects and such.
I don't see a problem with doing this; if you're keeping the phone awake with a long-running background task (audio recording in this case), then the phone can't sleep anyway. I wouldn't expect updating the widget to have a significant impact on battery use in this case.
Of course, the best thing to do is to run some tests on a real device, and compare battery use with and without widget updates, and make widget update interval a user preference.
The main reason widgets shouldn't update constantly is because of the battery consumption used to get the latest data from a server. Since the device will be on anyway, and the update is local to your data, it shouldn't have an impact that is noticeable.
If you were hitting a server instead of local data every second for that long, you would notice a significant draw on the battery.
I'm writing a sports app that needs to track the elapsed time of quarter/half/period. Elapsed time needs to be accurate to the second. The game clock needs to continue to run even if the user explicitly places the device in sleep mode by pressing the power button.
My first attempt at this involved using Handler.postDelayed() to trigger the clock ticks every 200ms and WindowManager.LayoutParms.FLAG_KEEP_SCREEN_ON to ensure that the "clock" wasn't stopped by a screen timeout. But I soon learned that it was possible to circumvent this approach by pressing the power button to manually put the device to sleep. In addition, the postDelayed() approach is experiencing some clock drift, apparently a result of the time spent in the run() method. The actual numbers are still accurate, but instead of being aligned, for example, on 5 second boundaries which are easily understood by users - the timers involved start to drift, resulting in some understandable user confusion.
After a bit of research I found techiques for using services, java timers, AlarmManager, and PartialWakeLock to implement timers. Services by themselves won't solve the problem associated with the device going to sleep. Java timers, like services, don't solve the problem with the device going to sleep. AlarmManager seems like a good approach, but I'm concerned that this isn't an appropriate use of AlarmManager (i.e., very short intervals between alarms). Using PartialWakeLock also looks promising, but by itself it doesn't address the clock-drift problem I'm experiencing.
I'm going to try a combination of AlarmManager and PartialWakeLock. The idea is that AlarmManager will help combat clock-drift and PartialWakeLock to help keep the code simple (fingers-crossed). I'm hoping that this approach will result in a reasonable balance between power conservation, code complexity, and user expectations. Any advice is greatly appreciated.
Thanks,
Rich
I've got a partial solution to my original post above. It doesn't yet address the clock drift associated with the time spent in calculations during the postDelayed() processing, but it is a step forward. In addition, it's deceptively simple, always a good sign.
It turns out I was using SystemClock.uptimeMillis() when I should have been using SystemClock.elapsedRealtime(). The difference between the 2 is subtle, but important.
As you might expect, my solution keeps track of elapsed time by accumulating durations between calls to postDelayed() - i.e., elapsed time = elapsedTime + lastClockInterval. As stated above, the original implementation used uptimeMillis(). Careful reading of the javadoc reveals that uptimeMillis() doesn't include time spent in "deep sleep", e.g., when the user presses the power button. But the elapsedRealtime() method does include time spent in "deep sleep" mode. All that was required to track time across deep sleep cycles was to replace the use of uptimeMillis() with elapsedRealtime(). Success! No need to use AlarmManager, PartialWakeLock, or anything else substantially more complicated. Granted, these methods still have uses, but they are overkill when implementing a simple elapsed-time clock or timer.
The next problem to tackle is with the clock-drift caused by the non-zero execution time associated with postDelayed() processing. I'm hoping that spawning a thread to do the processing will address this issue, allowing postDelayed() to more or less mimic an asynchronous call. Another approach would be to adjust the postDelayed() delay time to take into account the time spent in postDelayed(). I'll post my results.
On an unrelated note, during my investigation I treated myself to a CommonsWare Warescription. While I didn't directly use any ideas from this source for this problem, I do think that it is going to be my Android go-to information source for the foreseeable future. I've got an O'Reilly subscription through my day job, but I've found the CommonsWare books to be as least as good, if not better, source of information about Android development as the O'Reilly resources. And I have found the O'Reilly Safari resources to be pretty good. Interesting...
Cheers,
Rich
I'm sorry this is not quite an answer, but I feel your process is similar to mine, but there was little in regards to code to make it clear how you got around the sleep issue. I don't have drift, but the app does hang when it goes into sleep mode,then kind of resets forward when the display is active, then hangs again when the device sleeps. This is the core of the timer process.
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
// do something here to display
processTime(); // process what to be done on a sec by sec basis
try {
timerHandler.postDelayed(this, 1000
} catch (Exception ex){
}
}
};
Is there something here that I can do to allow it to continue when in sleep mode? This use to work on older version of android/devices.
Hello
In my android application i would like to get Time since when the app is opened.
Initially what i tried was getting the time when the app is loaded from the server and then taking the difference with the current time from the device.But by doing that if the user changes the time then i willnot be getting the actual time.
Its not posiible to hit the server again for the same.
Is there any way to achieve this in android?
Please share your valuable suggestions.
Thanks in advance:)
Try the "SystemClock" class, "uptimeMillis()" method.
Store the result in a variable when the app starts.
Echoing what I said for your other question, you first need to become familiar with the activity lifecycle and understand the novel meanings (almost meaninglessness) of common words like "open" and "start" in the life of an android app.
There isn't any way you can prevent the user from changing the system time - you just don't have the right to do that to users. Normally this should be a rare event, unless you do something that makes them want to, such as lock them out of a free version of your app after so many minutes. (However if the phone is on a mobile network, presumably the mobile network occasionally adjusts its time to correct for errors in the device's oscillator, or administrative time changes)
What you can do is check the system time on every entry point to your application. If it ever goes backwards, well... something is going on. If the clock has been set back, you could assume no time between the calls with the negative time difference and resume your time meter from there, at least keeping all the previous used time in your record.
It may be that there are cpu cycle counters which you could query and correlate to system time, but this may be highly device specific and may in fact be resettable. And it may get weird if the cpu frequency is demand throttled.
You might be able to set a countdown timer as a bound on the maximum possible time between entry points at which you could meter. I don't know if these work reliably across system time changes or not - ideally they would. Testing or reading the source will reveal.
Use elapsedRealtime in your onCreate() store it. More reliable.