I want to set alarm at particular time with hour and minute.
I am trying to do it this way:
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 11);
cal.set(Calendar.MINUTE, 30);
Intent intent = new Intent(this, AlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarm (AlarmManager.RTC_WAKEUP, calAlarm.getTimeInMillis(), pendingIntent);
But alarm is not fired at particular hour and minute.
I have seen many example on stackoverflow and other blogs, but that also didn't work for me.
Starting from Android 6.0 (API level 23), Android introduces Doze feature that extend battery life for users by managing how apps behave when a device is not connected to a power source.
Doze is particularly likely to affect activities that AlarmManager alarms and timers manage, because alarms in Android 5.1 (API level 22) or lower do not fire when the system is in Doze.
To help with scheduling alarms, Android 6.0 (API level 23) introduces two new AlarmManager methods: setAndAllowWhileIdle() and setExactAndAllowWhileIdle(). With these methods, you can set alarms that will fire even if the device is in Doze.
Note: Neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can fire alarms more than once per 9 minutes, per app.
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
if (Build.VERSION.SDK_INT >= 23) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
}
More info:
https://developer.android.com/training/monitoring-device-state/doze-standby.html
You can use:
AlarmManagerCompat.setAlarmClock(alarmManager, time, triggerIntent, showIntent)
You can find the docs here.
Related
I've searched around but did not found the solution. My application is required to show daily notifications on different times decided by user but alarmmanager is not working properly, If I set time for next few minute it will show notification but most of the time when I'm not using device it do not works.
this is what i've been trying to set repeating alarm.
Intent intent = new Intent(Reminder.this, AlarmReceiverDaily.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Reminder.this, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) Reminder.this.getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, targetCal.getTimeInMillis(), 24 * 60 * 60 * 1000, pendingIntent);
How I can set repeating alarm even if my device is in Doze mode from the following code?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(targetCal.getTimeInMillis(),pendingIntent),pendingIntent);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
alarmManager.setExact(AlarmManager.RTC, targetCal.getTimeInMillis(), pendingIntent);
else
alarmManager.set(AlarmManager.RTC, targetCal.getTimeInMillis(), pendingIntent);
If I can not use setAlarmClock() with repeating alarm then what solution you prefer to make repeating alarm and it must work.
You have to use:
if( Build.VERSION.SDK_INT >= 23 ){
alarmManager.setExactAndAllowWhileIdle( ... );
}
Calendar calendars = Calendar.getInstance();
calendars.set(Calendar.HOUR_OF_DAY, hour);
calendars.set(Calendar.MINUTE, min);
calendars.set(Calendar.SECOND, 0);
calendars.set(Calendar.MILLISECOND, 0);
calendars.set(Calendar.AM_PM, timezone);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), currentTime, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT < 23) {
if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendars.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendars.getTimeInMillis(), pendingIntent);
}
} else { alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendars.getTimeInMillis(), pendingIntent);
}
In my App if I set Alarm within an hour then it is working fine but for long duration it is not working.
I have searched a lot regarding the alarm issue we are facing and found out that in latest android updates android OS is killing the broadcast receivers if memory needed for other task OR in low battery state OR without a reason.
In some cases if mobile is in idle / doze mode that time also alarm is not working.
I had been tasked with developing an alarm app. Something simple which lets users set an alarm at a specific time and select a music file that should play when the alarm goes off. The app works great on phone like Samsung, Motorola, and Nexus but on Xiomi, Oppo, Vivo phones the alarm does not go off at the correct times and sometimes it does not fire at all. I have used Android's AlarmManager APIs. I am wondering if there is something else I need to do to get the alarm to work as expected on devices like xiomi, oppo, and vivo. Most of the solutions on StackOverflow have not worked out for me. If there are devs here in this subreddit who have worked with AlarmManager APIs before or worked on Apps with Alarm features, id really appreciates some more insight into AlarmManager APIs and why they don't work as expected across all phones and if there are any alternatives I should be using.
Bellow is the method which will help you, Which I tested with the different-different device it's working.
/**
* Method for start Alarm on Defined time
*
* #param context
*/
public static void startAlarm(Context context,int minutes) {
Logger.print("AlarmReceiver startAlarm called");
Intent alarmIntent = new Intent(context, WakefulBrodcastReceiverService.class);
alarmIntent.setAction("testAPP");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 123451, alarmIntent, 0);
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
manager.cancel(pendingIntent);
long alarmPeriodicTime = System.currentTimeMillis() + Utils.getTimeInMilliSec(Constant.TimeType.MINUTE, minutes);
if (Build.VERSION.SDK_INT >= 23) {
manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
manager.setExact(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
} else {
manager.set(AlarmManager.RTC_WAKEUP, alarmPeriodicTime, pendingIntent);
}
}
Since the introduction Doze Mode and App StandBy managing alarms have changed. The problem I'm facing is my alarm manager fires correctly on KitKat, Lolipop and Marshmellow devices but above API 23 it does not fire unless the app is in foreground or background. But if the app is killed, the alarms are stopped.
Checked out Google Keep Application on my Android 7, turns out it does the same.
But Google Calendar fires regardless of whether the app is killed or not.
Done some reading and found out setExactAndAllowWhileIdle method on the alarm manager ensures to break the doze mode and trigger your alarm.
But it does not work, is there anything I'm missing here?
Here's my code:
Intent alertIntent = new Intent(this, NotificationPublisher.class);
alertIntent.putExtra("Hello", "Meal Time");
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
int id = (int) System.currentTimeMillis();
if (Build.VERSION.SDK_INT < 23) {
if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, delay, PendingIntent.getBroadcast(this, id, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, delay, PendingIntent.getBroadcast(this, id, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
}
} else {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, delay, PendingIntent.getBroadcast(this, id, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
}
Broadcast Receiver:
public class NotificationPublisher extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("Hello");
Log.d("Called", "Meal Time");
}
Manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name=".NotificationPublisher" />
Because of battery optimisation it is not working,i turned off the battery optimisation of particular app, it is working fine in oneplus 3.
You wanna white-list your app from battery optimisation programatically, check this link stackoverflow.com/a/42651399/3752079
Try with adding below line for your alertIntent
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,myIntent, 0);
So I am having an issue with AlarmManager. I am trying to run some code every 2 minutes, which works okay while the phone is awake, but not when the device goes to sleep - during sleep, the intervals are perfectly 5 minutes apart.
Since my desired interval is 2 minutes, this is roughly 250% off my target interval, which for my specific application is not acceptable.
I am aware of the changes in API 19, and have followed suggestions to re-schedule the alarm using setExact() within my BroadcastReceiver. Code is below:
The code used to trigger BroadcastReceiver:
Intent intent = new Intent(this, AlarmReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
mAlarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 3000, pendingIntent);
And this code is in my BroadcastReceiver which re-schedules the alarm:
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "AlarmService Triggered.", Toast.LENGTH_SHORT).show();
Log.d(this.getClass().getSimpleName(), "Service triggered");
Intent newIntent = new Intent(context, this.getClass());
mPendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 120000, mPendingIntent);
}
Does anyone have suggestions as to how I could fix this? It is very frustrating that AlarmManager is totally ignoring my wish to have an alarm fire at an exact time. Is there any alternative that will allow me to schedule code at 2 minute intervals like I want?
DEVICE: Samsung Galaxy S6, OS 5.1.1
As #Francesc suggested, it ended up being the Samsung device. Tried it on another phone, now it works flawlessly.
Let this be a lesson to you - don't buy Samsung, they do weird stuff, lol.
Replace ELAPSED_REALTIME_WAKEUP with RTC_WAKEUP.
This is how I schedule alarms:
mTargetTime = System.currentTimeMillis() + timeout * 1000L;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, mTargetTime, mPendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, mTargetTime, mPendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, mTargetTime, mPendingIntent);
}