Hello Guys
I want to create an alarm which run every second . I have searched many code but fond no solution , Please suggest some references .
Thanks
Amit Sharma
You can do this, create a CountDownTimer , say how long you want it to last for in the first param (in milliseconds), then set a period of time to run a piece of code in the second param. In the onTick() method, this is the code that will run in the interval specified in the second param, onFinish() is called when the period of the countdown is finished. Call the start() method on the CountDownTimer object when you want it to run.
int howLongTimerLastsInMilliseconds = 3000 // 3000 milliseconds
int tickEverySecond = 1000 // 1000 milliseconds == 1 second
CountDownTimer countDownTimer = new CountDownTimer(howLongTimerLastsInMilliseconds,tickEverySecond ) {
#Override
public void onTick(long millisUntilFinished) {
//do some work every second
}
#Override
public void onFinish() {
//do something when the time is up
}
};
countDownTimer.start();
According to the documentation:
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS
will shift alarms in order to minimize wakeups and battery use. There
are new APIs to support applications which need strict delivery
guarantees; see setWindow(int, long, long, PendingIntent) and
setExact(int, long, PendingIntent). Applications whose
targetSdkVersion is earlier than API 19 will continue to see the
previous behavior in which all alarms are delivered exactly when
requested.
Also this question was rised at code.googls.com and here is an explanation of it:
Suspiciously short interval 5000 millis; expanding to 60 seconds
This is working as intended, though is at present inadequately
documented (and we're aware of that side of the problem). Speaking
very generally: short-period and near-future alarms are startlingly
costly in battery; apps that require short-period or near-future work
should use other mechanisms to schedule their activity.
So, there is no inbuild way how to solve your issue using Alarm. And you should look out for another mechanisms or (very rough solution) use 60 independent alarms
Related
I'm working on an app where I have to read data from multiple sensors and send it to a remote server every 15 minutes. This has to be done when the app is closed/killed as well and I also have to be sure it always executes. I also want to be sure it happens (almost) exactly every 15 minutes (+-1 minute difference is the upper limit).
At this point, I've found 3 options: using Workmanager, Alarmmanager or using a foreground service. Following the documentation, Workmanager seems the way to go for background tasks, however, after having done some reading, Alarmmanager seems to be a safer choice (Workmanager sometimes has troubles with doze mode, and the timing isn't exact because it uses a flex period of at least 5 minutes). And a foreground service is not really allowed for this kind of task (it's not really long running, it's just a periodic task) and is being limited in newer Android versions. Do you think it would be a good idea to use an Alarmmanger for this task, or should I use something else? Thanks!
TODO Background scheduling.. You can use this method todo your stuff..
KOTLIN;
val service = Executors.newSingleThreadScheduledExecutor()
val handler = Handler(Looper.getMainLooper())
service.scheduleAtFixedRate({
handler.run {
// Do your stuff here, It gets loop every 15 Minutes
}
}, 0, 15, TimeUnit.MINUTES);
JAVA;
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
Handler handler = new Handler(Looper.getMainLooper());
service.scheduleAtFixedRate(() -> {
handler.post(() -> {
// Do your stuff here, It gets loop every 15 Minutes
});
}, 0, 15, TimeUnit.MINUTES);
How to update widget per second ?
I used AlarmManager but it only works on below kitkat version.
Here, i am making user wait for 30 seconds on a screen and hiding the view and hitting service when it finishes. You can customize according to your need.
CountDownTimer timer = new CountDownTimer(31000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timer_text.setText("Remaining Seconds. " + millisUntilFinished / 1000 + " s");
if (count >= 30) {
} else {
count++;
}
}
#Override
public void onFinish() {
timer_text.setVisibility(View.GONE);
/// VOLLEY SERVICE
}
}.start();
AlarmManager cannot have a timeout less than 20 seconds. Any timeout less than that will be rounded up.
First off, I would question whether you actually need it updated every second. That's an incredible amount of processing power used, and pretty much against the idea of a widget. If it needs to be updated that frequently it should be an app. If your updates are coming from a server and you want to display them immediately, look into push messaging instead. Then you only need to update when you receive a message, no alarms or timers needed.
Secondly- the way you do a timer for short periods like that is via Handler.postDelayed. It can have a much smaller resolution. However it may not run if the phone is asleep.
Let's say I'm developing a game and there exists such thing as respawn. The user may respawn after 15 minutes. Is there any common practice to avoid time cheating? I mean, nothing can stop user from changing system time and set it to future. I know, partially this can be resolved by using server side, but nothing can stop user from disabling the network at all.
PS. the game is cross platform so the solution is interesting for both antroid and iOS. PS2. I know a couple of games that have the solution.
For something like this you could simply start your own timer completely separate from the system time. If you start a 15 minute countdown when a player dies they won't be able to modify your internal timer. I'm not as familiar with iOS dev (NSTimer looks like a possibility) but I know in Android it's as easy as:
// create 30 second internal countdown timer
new CountDownTimer(30000, 3000) {
public void onTick(long millisUntilFinished) {
// store time remaining in database every 3 seconds in case user exits the game
dbHelper.updateDeathTimer(millisUntilFinished);
}
public void onFinish() {
// player respawns now
}
}.start();
To combat the issue of players closing the game I would suggest you also set up your internal timer to cache its' current state in the database at a regular interval, say every 30 seconds or so if you were going to stick with a 15 minute timer.
Below is some psuedocode for what it might look like when a player exits the game while they are dead and our respawn timer was still in progress.
// When game resumes check database and begin updated death timer if necessary
onGameResume() {
if(dbHelper.isUserDead()) {
// resume respawn timer
new CountDownTimer(dbHelper.getRespawnTime(), 15000) {
public void onTick(long millisUntilFinished) {
// store time remaining in database every 15 seconds in case user exits the game
dbHelper.updateDeathTimer(millisUntilFinished);
}
public void onFinish() {
// player respawns now
}
}.start();
}
}
You can store the time of the event (spawn in your case), and then run a timeIntervalSinceReferenceDate against it and see if it exceeds your limit (15 minutes).
The risk on the iOS side is that the app goes to the background and the timers stop.
It's not actually the answer, but just an idea.
What if we use tickCount? Each operating system has this property.
For instance, android.os.SystemClock.elapsedRealtime() in Android and
[NSProcessInfo processInfo].systemUptime in iOS
They should give required values.
Please help me. Why does AlarmManager not exactly repeats an event when the repetition period of more than one day?
Here is my code to run AlarmManager. The variable time_period contains the following value 60*1000*60*24*7 which is equal to 7 days. In the end, if I change the date on your phone, the event is triggered by 6-4-7-7-7-7 days.
This can be seen in the logs of the application (See link http://prntscr.com/7kdqbw ) Thanks in advance for your reply.
Intent notification = new Intent(this , ServiceReminders.class);
notification.putExtra("backup", "backup");
AlarmManager alarmManagerBackup = (AlarmManager)getSystemService(ALARM_SERVICE);
PendingIntent pibackup = PendingIntent.getService(this, 3, notification, 10);
if (sdkVersion < 19) {
alarmManagerBackup.setRepeating(AlarmManager.RTC_WAKEUP, 0, time_period, pibackup);
}
else if (sdkVersion >= 19) {
alarmManagerBackup.setInexactRepeating(AlarmManager.RTC_WAKEUP, 0, time_period, pibackup);
}
Log.d("ServiceManagerNotification", "AlarmBackup sdkVersion = "+sdkVersion);
You are explicitly leveraging the inexact alarms by calling setInexactRepeating(). Unsurprisingly, this results in your alarms being set at inexact intervals.
The problem is further compounded by the fact that you are supplying a custom period. If you do not use one of the pre-defined intervals, then the framework will simply call setRepeating() using your interval instead of using setInexactRepeating().
From the documentation for the intervalMillis parameter:
interval in milliseconds between subsequent repeats of the alarm. Prior to API 19, if this is one of INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_HALF_DAY, or INTERVAL_DAY then the alarm will be phase-aligned with other alarms to reduce the number of wakeups. Otherwise, the alarm will be set as though the application had called setRepeating(int, long, long, PendingIntent). As of API 19, all repeating alarms will be inexact and subject to batching with other alarms regardless of their stated repeat interval.
In the end, regardless of how you set this alarm, it will be inexact if you set it as a repeating alarm and there isn't a whole lot you can do about it.
If you need more precision, you should use either setWindow() or setExact() and set the next alarm every time your alarm triggers. Although if you are only performing an action once a week, it is likely that in the end you don't need that precision.
I have a problem with this code used for Android (Java)
handler.postDelayed(new Runnable(){
public void run(){
// Your code goes here...
}
}, 500);
If the delay is about 500ms then the program seems to repeat the task at 0.5s, but if I change to less than 100ms or even less it does not follow any more. I test the brightness change and for a while it can repeat the change of brightness at that rate, but then slow down and come back to normal flash rate again. It seems unstable. Do you have any code that give exact delay regardless of the load of the phone's CPU.
Many thanks
Not from Java, no; stock Java isn't a real-time system.
Timing precision is subject to the whims of the JVM and the OS's scheduler. You may be able to get incrementally more precise, but there's no guarantee of the kind of precision you're looking for.
You might be able to do something more precise if you use a CountDownTimer which has a periodic tick. Essentially you set it to count down for a period which can be hours if need be, and there are two methods one method is called on each tick, and the other at the end of the timer at which point you could start another one. Anyway you could set the tick to be very fast, and then only kick off the code at the delay point by check the actual time difference in the click. I think thats about the best you could do. Essentially inside the tick you would issue a signal if the right amout of time had actually passed. That signal would either kick off the thread or release something the already running thread was waiting on. What is the value of the CountDownTimer, I guess its just that you can do a very frequent polling, and elapsed time check. Although its not guaranteed, the time between the ticks you can set it to a high frequency and check/poll very frequently. This could lead to a smooth performance not unlike a realtime system. Its more likely to be accurate because its just issuing a signal and not taking up the resources of threading just to issue the signal. You might also try an IntentService to perform the tasks and just call startService(intentToIntentService) each call. See if the threading works better inside a service like IntentService which does queue them up I believe.
Date startDate = new Date();
long startTime = startDate.getTime();
// Tick called every 10th of a second. OnFinish called at Signal.
CountDownTimer ctDownTimer = new CountDownTimer(30000, 100) {
long startIntervalTime=startTime;
public void onTick(long millisUntilFinished) {
Date now = new Date();
long nowTime = now.getTime();
if ((startIntervalTime - nowTime) > 100)
{
issueSignal();
intervalStartTime=nowTime;
}
now=null;
}
public void onFinish() {
Log.d("MyClass", "Done") // Maybe start out.
}
}.start();