Though this question is repeated over and over here on SO, but non of the solutions are working, in the code below it should fire for the first time after 10 seconds from launching my activity, but it launch immediately. And I'm using FLAG_UPDATE_CURRENT so there's no past time to fire immediately as I'm not setting it at specific hour/minute/sec. Could you please bring my attention to what I'm missing.
I'm testing on Android 5.0 Targeting API 4.0+
compileSdkVersion 23
minSdkVersion 16
targetSdkVersion 23
Intent myIntent = new Intent(this, check.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC, 10000, (AlarmManager.INTERVAL_DAY / 8), pi);
And this is my check.class in AndroidManifest.xml
<receiver
android:name=".Check"
android:exported="false" />
10000 on the real time clock is always going to be in the past, so your alarm fires immediately. You want System.currentTimeMillis() + 10000 as the second argument in the setRepeating() call.
I would point out that setRepeating() is inexact as of KitKat, so the actual time the alarm fires may be off. If it matters, use the setExact() method instead, setting the alarm again for the desired interval each time it fires.
Related
I have simply functional for start service and repeat he:
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
PendingIntent pIntent = PendingIntent.getService(mContext,
SendStatusService.SEND_STATUS_SERVICE_CODE,
mIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 2000,
mIntervalInMs,
pIntent);
I understand the documentation: alarm manager regardless of device state (sleep or not) start service through 2000 ms and repeat with interval mIntervalInMs.
But service start working after 30-50 sec after running this code. What i make wrong or no understand the documentation?
setRepeating() is "inexact" with a targetSdkVersion of 19 or higher when running on an API Level 19+ Android device. Hence, your results are not surprising. The events will occur somewhere around the desired time (until Android 6.0's Doze mode kicks in), but they will not occur exactly at the desired time.
I have a TimePicker and a Button and I want to set an alarm when the user clicks on the Button at the time specified.
It gets the hour well when I click on the button but the alarm is being fired sometimes at the specified time, but not always. It is fired at the specified time less times than it does not fired. Most of the times the BroadcastReceiver does not fire at the specified time, it fires with a delay.
This is the code that I have right now:
On Alarm class (code refered to the BroadcastReceiver)
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
Calendar cal= Calendar.getInstance();
cal.set(Calendar.MONTH,cal.get(Calendar.MONTH));
cal.set(Calendar.YEAR,cal.get(Calendar.YEAR));
cal.set(Calendar.DAY_OF_MONTH,cal.get(Calendar.DATE));
cal.set(Calendar.HOUR_OF_DAY,hour);
cal.set(Calendar.MINUTE,minutes);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1000 * 60 * 5, alarmIntent);
where hour and minutes are the hour and minutes retrieved from the TimePicker.
On AlarmReceiver class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("prove", "We enter on BroadcastReceiver");
}
}
On Manifest.xml
<receiver
android:name=".AlarmReceiver"
android:enabled="true" >
</receiver>
For example, I have put a log to see what hour I was retrieving from TimePicker before show the log of BroadcastReceiver. I clicked it at 16:48 (on the TimePicker) and this is the result:
12-06 16:47:02.951 7980-7980/com.project.user.project D/prove: hour: 16:48
12-06 16:50:23.727 7980-7980/com.project.user.project D/prove: We enter on BroadcastReceiver
12-06 17:00:01.070 7980-7980/com.project.user.project D/prove: We enter on BroadcastReceiver
As you can see, the BroadcastReceiver has been fired two times at 16:50 and 17:00 when I suppose that they should fire at 16:48 and 16:53 because I have set that it will be a delay of 5 minutes between them, not 10 minutes as in this case.
So, what can I do to fire the alarm at the exact time and not fire it with a delay? Am I missing some configuration?
Thanks in advance!
As mentioned in the documentation, setRepeating is inexact.
As of API 19, all repeating alarms are inexact. If your application
needs precise delivery times then it must use one-time exact alarms,
rescheduling each time as described above. Legacy applications whose
targetSdkVersion is earlier than API 19 will continue to have all of
their alarms, including repeating alarms, treated as exact
So, to fire the alarm at the exact time as of API 19, use setExact, and inside each alarm set the next alarm.
Schedule an alarm to be delivered precisely at the stated time.
Use setInexactRepeating
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), 1000 * 60 * 5, alarmIntent);
And you can check my code what I did in my app.I worked perfect.
pendingIntent = PendingIntent.getBroadcast(this, _id, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeToAlarm, AlarmManager.INTERVAL_DAY, pendingIntent);
May it help..
I want to call a BroadcastReceiver after specific interval of time. BroadcastReceiver is calling but it is not calling exactly after 10 seconds sometimes it call is 20 sec sometimes more than 20 seconds. I want to call BroadcastReceiver exactly after 10 seconds
This is the code of MainActivity
Intent myIntent = new Intent(MainActivity.this, SampleReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, wakeupTime,1000 * 10, pendingIntent);
This is code of broadcastreceiver
public class SampleReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("Brodcast","receiver");
}
}
This is my log file
09-05 14:48:21.444 18222-18222/com.loconav.partners.tracker E/Brodcast: receiver
09-05 14:49:21.509 18222-18222/com.loconav.partners.tracker E/Brodcast: receiver
09-05 14:50:31.578 18222-18222/com.loconav.partners.tracker E/Brodcast: receiver
09-05 14:51:21.618 18222-18222/com.loconav.partners.tracker E/Brodcast: receiver
From the documentation of AlarmManager:
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.
Exact repeating is not possible currently with a single set of an alarm on API level 19+.
If you would like your repeating alarm to fire exactly when you want it, then you should use setExact() (or setExactAndAllowWhileIdle() according to your needs) and reschedule it every time it fires.
I don't know whats in wakeupTime.
The code works for me as
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),1000*10,pendingIntent);
First, use ELAPSED_REALTIME_WAKEUP type, because you don't need fire alarm at a specific time of day. When you use rtc time, it can be updated by the system - when it syncs with time server, and your alarm could be never fire up at all.
Second, do not use BroadcastReceivers defined as subclasses of Activity - they should be set up in AndroidManifest.xml, because if your activity is destroyed - you will never receive your Intent.
I thinking you have to provide unique request code to get broadcast method.
Intent myIntent = new Intent(MainActivity.this, SampleReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, uniqueRequestCode, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, wakeupTime,1000 * 10, pendingIntent);
uniqueRequestCode could be the System.currentTimeInMilliSecond
I am using an AlarmManager in a Service to be triggered every minute.
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0,
getUpdateServiceIntent(mContext), PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
// Cancel any pending Intent
am.cancel(pendingIntent);
// Set a new one
am.set(AlarmManager.RTC_WAKEUP, 60000, pendingIntent);
On the Samsung S5 Neo :
When the screen is active, it is working as expected.
When the screen is off, it is triggered every 5 minutes (instead of one).
I try this exact same code on S5 Mini (with Android 4.4), Nexus 5 5.1 and Nexus 5 6.0, this code is working fine.
targetSdkVersion is 19.
Any idea how to keep the AlarmManager working correctly when screen is off ?
The delay is still 5 minutes, even if I ask for 30 seconds.
EDIT :
I also tried the 'setExact' method, but it didn't change anything. Still have a 5 minutes interval between each alarm.
You should probably use
AlarmManager#setExact(int type, long triggerAtMillis, PendingIntent operation)
instead of
AlarmManager#set(int type, long triggerAtMillis, PendingIntent operation))
Take a look
From google :
AlarmManager#set(int type, long triggerAtMillis, PendingIntent operation))
Note: Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later. The OS will use this policy in order to "batch" alarms together across the entire system, minimizing the number of times the device needs to "wake up" and minimizing battery use. In general, alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.
Edit :
What i am using for an alarm application :
Manifest :
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Java Code :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(nextAlarm.getTimeInMillis(), pendingIntent);
alarmManager.setAlarmClock(alarmClockInfo, pendingIntent);
}else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(android.app.AlarmManager.RTC_WAKEUP, nextAlarm.getTimeInMillis(), pendingIntent);
}else {
alarmManager.set(android.app.AlarmManager.RTC_WAKEUP, nextAlarm.getTimeInMillis(), pendingIntent);
}
I want to show toast at a specific time using AlarmManger but my toast is not shown at given time? Help me.
My code is as follows:
private void startAlarm() {
Calendar cal=Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH,9);
cal.set(Calendar.MONTH,7);
cal.set(Calendar.YEAR,2015);
cal.set(Calendar.HOUR_OF_DAY,2);
cal.set(Calendar.MINUTE,55);
cal.set(Calendar.AM_PM,Calendar.PM);
Intent intent = new Intent(this, WelcomActivity.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)getApplicationContext().getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
Toast.makeText(this, "Alarm worked.", Toast.LENGTH_LONG).show();
}
The documentation for setInexactRepeating states:
Your alarm's first trigger will not be before the requested time, but it might not occur for almost a full interval after that time.
[edit thanks to ci_]
Note: as of API 19, all repeating alarms are inexact. If your
application needs precise delivery times then it must use one-time
exact alarms, rescheduling each time as described above. Legacy
applications whose targetSdkVersion is earlier than API 19 will
continue to have all of their alarms, including repeating alarms,
treated as exact.
So you need to use one-time exact alarms and reschedule as described in the documentation.