Below is my code
public static void startAlarmManager(Context context, Date date) {
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
alarmIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
PendingIntent recurringAlarm = PendingIntent.getBroadcast(context.getApplicationContext(), NOTIFY_ME_ID,
alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarms.cancel(recurringAlarm);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarms.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, date.getTime(), recurringAlarm);
} else if (Build.VERSION.SDK_INT >= 19) {
alarms.setExact(AlarmManager.RTC_WAKEUP, date.getTime(), recurringAlarm);
} else {
alarms.set(AlarmManager.RTC_WAKEUP, date.getTime(), recurringAlarm);
}
}
This code works correctly in all device on which I have tested. But I am facing issue with Wiko Jerry mt6580.
In this device alarm is triggered after five minutes, of the intended time.
Note: The tests made with the devices connected to charger, to not
active o doze mode.
Any suggestions why I am getting this problem, or how to solve it would be of great help.
-Thanks!
Related
how to use setallowWhileIdle method for repeatetive task in alarmManager,
because I think the only method that overcome doze mode,
I need to work 24*7 task in repeatetive mode,
is there any example please help I am new to android
private void scheduleAlarm() {
try{
Intent intent = new Intent(getApplicationContext(), KeepAliveAlarmReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this,
KeepAliveAlarmReceiver.REQUEST_CODE,
intent, PendingIntent.FLAG_MUTABLE);
long firstMillis = System.currentTimeMillis();// alarm is set right away
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP,firstMillis,60000, pIntent);
System.out.println("enters into alarm manager");
}catch (Exception e)
{
e.printStackTrace();
Toast.makeText(this, e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
I need to do like this on setallowwhileIdle method it doesn't support repeatetive task timer.
Please read this post by #lyc001. Android - Repeating Alarms Allowed While Idle
It says
the only Apis available in AlarmManager for
Android 23 are setExactAndAllowWhileIdle and setAndAllowWhileIdle
which are not for repeating alarms.
You should use either of these APIs and "reschedule the alarm every time it fires".
So, A alarm that registers another alarm, and so on.
Here is the code to make your life easier!
Register for the first time (MainActivity.java)
AlarmManager alarmManager=(AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), AlarmRBActivity.class);
boolean alarmUp = (PendingIntent.getBroadcast(getApplicationContext(), 007,
intent,
PendingIntent.FLAG_NO_CREATE) != null);
if(!alarmUp){
long triggerTime = intent
.getLongExtra("TRIGGER_TIME", System.currentTimeMillis());
triggerTime += TimeUnit.MINUTES.toMillis(2);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 007, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}else if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}
Log.e("alarm", "Alarm registered!");
}else{
Log.e("alarm", "Alarm already registered!");
}
Register when triggered/ Register in loop (AlarmBRActivity.java)
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 007, AlarmIntent, 0);
long triggerTime = intent
.getLongExtra("TRIGGER_TIME", System.currentTimeMillis());
triggerTime += TimeUnit.MINUTES.toMillis(2);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}else if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}
Source:
Android AlarmManager not working on some devices when the app is closed
I have implemented AlaramManager with background service, It works fine on devices below Oreo. But doesn't work on android Oreo and above as Google stopped background services from working on Oreo and Above.
Is there any source code or any kind resource which will help me to set alarms on android Oreo or above devices?
After searching for a while I found out about JobsIntentService, but couldn't found enough information about it. And I don't know if it is the way to go. Basically, I want to show notifications on particular dates and times.
Thanks in Advance.
Please try bellow method it will work for you.
/**
* Method for start Alarm on defined minute
* #param minutes Minute when you want to start after current time
* #param context
*/
public static void startAlarm(Context context, int minutes) {
Logger.print("AlarmReceiver startAlarm called");
Intent alarmIntent = new Intent(context, WakefulBroadcastReceiverService.class);
alarmIntent.setAction("testAPP");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 123451, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
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);
}
}
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.
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);
}
I have this method which should schedule alarms but when the time arrives it doesn't start the pendingintent ??
public void setAlarm(String name, long time) {
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent dialog = new Intent(this, SubActivity.class);
dialog.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getActivity(this, 0, dialog, 0);
if (Build.VERSION.SDK_INT >= 19) {
if (System.currentTimeMillis() < time) {
am.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, pi);
}else{
time+=(AlarmManager.INTERVAL_DAY*7);
am.setExact(AlarmManager.RTC_WAKEUP, time, pi);
}
} else {
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, AlarmManager.INTERVAL_DAY * 7, pi);
}
}
The problem is you are using a PendingIntent for an Activity, which will not necessarily keep the device awake long enough for the Activity to get started. You'll have to use a PendingIntent for a BroadcastReceiver which leverages a wake lock to keep the device awake until your app code can run. WakefulBrodcastReceiver is a good choice, or you can roll your own as needed. See this article for an explanation and sample of how to use alarms to wake the device: http://po.st/7UpipA