Android AlarmManager.setExact() not firing - java

I am having trouble with using Alarm Manager to fire a pending intent in the future. I have been at it for hours, and do not understand what I am doing wrong. Any help would be greatly appreciated.
This works, sending a broadcast immedietely:
_context.startService(notificationIntent);
This works, sending a broadcast in ~30 seconds:
if (mgr != null)
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 30000, AlarmManager.INTERVAL_DAY * 7, pendingNotificationIntent);
This works, sending a broadcast in ~30 seconds:
if (mgr != null)
mgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 30000, AlarmManager.INTERVAL_DAY * 7, pendingNotificationIntent);
But for some unknown reason, doing this fails. The broadcast is never triggered. When I take System.currentTimeMillis(), and subtract it from my trigger...it shows that the trigger is indeed in the future:
if (mgr != null)
mgr.setExact(AlarmManager.RTC_WAKEUP, trigger, pendingNotificationIntent);
I am printing my variable 'trigger' (type long) to console, and it is definitely a valid time (according to epochconverter.com). The value it is printing currently (just for reference) is 1521144300000, which elapsed a few minutes ago..never having fired my alarm;
Here is most of the setup:
Intent notificationIntent = new Intent(_context, com.example.example.NotificationReceiver.class)
.setAction(ACTION_SHOW_NOTIFICATION)
.putExtra(EXTRA_NOTIFICATION_TITLE, _title)
.putExtra(EXTRA_NOTIFICATION_BODY, newBody)
.putExtra(EXTRA_NOTIFICATION_TRIGGER_TIME, trigger);
AlarmManager mgr = (AlarmManager) _context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingNotificationIntent = PendingIntent.getBroadcast(_context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Log.d(TAG, "trigger time: " + trigger);
if (mgr != null) mgr.setExact(AlarmManager.RTC_WAKEUP, trigger, pendingNotificationIntent);
I receive the trigger time from the back-end, which appears correct in every response.
This also never fires:
if (mgr != null) mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, trigger, AlarmManager.INTERVAL_DAY * 7, pendingNotificationIntent);

There are some considerations depending in the Android version in which you are testing the alarm, but if you are testing for Android 6 or later then try the next code:
// Init the Alarm Manager.
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Setting the PendingIntent to be fired when alarm triggers.
Intent serviceIntent = new Intent(context.getApplicationContext(), YourService.class);
PendingIntent pendingServiceIntent = PendingIntent.getService(context, 0, serviceIntent, 0);
// Set the alarm for the next seconds.
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + seconds * 1000, pendingServiceIntent);

Related

How do I know the number of seconds remaining until the alarm goes off?

Scenario
i am developing an app that works kind of like subscription, i start an alarm manager for days, suppose the alarm manager has started yesterday and it should go off tomorrow, how do i know exact time remaining till alarm manager goes off?
// ALARM_MANAGER setting to expired
SharedPreferences alarmpreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor alarmEditor = alarmpreferences.edit();
alarmEditor.putString("ALARM_MANAGER", "active");
alarmEditor.apply();
AlarmManager service = (AlarmManager) getApplicationContext()
.getSystemService(getApplicationContext().ALARM_SERVICE);
Intent i = new Intent(getApplicationContext(), MyReceiver.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pending = PendingIntent.getBroadcast(getApplicationContext(), mainAlarmRequestCode, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// Start 20 seconds after boot completed
int secondTime = Integer.parseInt(expireTime)*60;
cal.add(Calendar.SECOND, secondTime);
//
// Fetch every 20 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pending);
I check to see if the alarm manager is running in the 0 background with this method.
Intent i = new Intent(getApplicationContext(), MyReceiver.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
boolean alarmUp = (PendingIntent.getBroadcast(getApplicationContext(), mainAlarmRequestCode, i, PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp) {
Log.d("myTag", "Alarm is already active");
Toast.makeText(this, "alarm manager is active!", Toast.LENGTH_SHORT).show();
//alarm is active check alarm manager counter time
} else {
Toast.makeText(this, "alarm manager is not active!", Toast.LENGTH_SHORT).show(); }
The alarm manager is active, but how do I know the number of seconds remaining until the alarm goes off?
Any help would be appreciated!
You can try to store the expiration date of your AlarmManager and run a test at regular interval, to check if the current date is greater than the expiration one.

Set multiple alarms using request code

I wanna set multiple alarm using request code.
I give different values of the request codes to each alarm, but the alarmManager still executes only the last set alarm.
Here's my existing code:
public void Alarm(){
Intent intent = new Intent(MainActivity.this, BroadCast.class);
alarmID = (int)(System.currentTimeMillis() % 1000000000); //for request code
PendingIntent sender = PendingIntent.getBroadcast(
MainActivity.this, alarmID, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DATE),hours,mins,0);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),am.INTERVAL_DAY, sender);
}
try setRepeating instead of setInexactRepeating you will get repeating alarm.
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ (5 * 1000),5 * 1000, pendingIntent);
As of Android 5.1 (API version 22) there is a minimum period of 1 minute for repeating alarms. If you need to do work within one minute, just set the alarm directly, then set the next one from that alarm's handler, etc. If you need to do work within 5 seconds (for example), post it to a Handler instead of using the AlarmManager.
Good documetion here :
https://en.proft.me/2017/05/7/scheduling-operations-alarmmanager-android/

Android : How to use same AlarmManager in loop?

I write bellow method for alarm.
public void alarm(int time){
Intent intent = new Intent(MainActivity.this, Alarm.class);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0 , intent, 0);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+time*1000, pi);
}
This method working perfectly. But the problem when I call the method more than one time. Like,
alarm(10);
alarm(50);
This time it only invoke alarm(10); But don't invoke alarm(50);
Anyone please help why it show this problem!
Your PendingIntent has the same properties both times you call your method. When you call PendingIntent.getBroadcast() the second time it will return the PendingIntent that was already created the first time.
If you want the alarm to trigger twice you need to do something like this:
public void alarm(int time, int requestCode){
Intent intent = new Intent(MainActivity.this, Alarm.class);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), requestCode , intent, 0);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+time*1000, pi);
}
And then call it like this:
alarm(10, 0);
alarm(50, 1);
You are giving the same ID (0)
You need to use different unique id. use different pending intent id like this. you can use millisecond as id.
public void alarm(int time, int requestCode){
Intent intent = new Intent(MainActivity.this, Alarm.class);
Long timeToMilliSeconds = timeToMilliSeconds(hour, minute);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), timeToMilliSeconds , intent, 0);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+time*1000, pi);
}
You are giving the same ID 0 (the second parameter in PendingIntent::getBroadcast) to more than onePendingIntent. This is your mistake.
Depending on the FLAG you set, the behavior may vary.
Consider either using a different ID for each PE or one of the standard flags.
Also see:
Wrong pending intent is being triggered
How does android compare pending intents
Adding flags to PendingIntent
// context variable contains your `Context`
AlarmManager mgrAlarm = (AlarmManager) context.getSystemService(ALARM_SERVICE);
ArrayList<PendingIntent> intentArray = new ArrayList<PendingIntent>();
for(i = 0; i < 10; ++i)
{
Intent intent = new Intent(context, OnAlarmReceiver.class);
// Loop counter `i` is used as a `requestCode`
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, i, intent, 0);
// Single alarms in 1, 2, ..., 10 minutes (in `i` minutes)
mgrAlarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 60000 * i,
pendingIntent);
intentArray.add(pendingIntent);
}
Call it like this
alarm(10, 0);
alarm(50, 1);
For more than one Pendingintent it needs different id so in the caller method pass
different id.

I want to give notification to the user (mobile application) when the if block is execute. this code doesn't work, what is wrong with my code?

if (200 <= intId && intId <= 250) {//if there is some Thondering give a alert
Notification noti = new Notification.Builder(MainActivity.this)
.setTicker("Tickertittle")
.setContentTitle("ELEKTRA WEATHER ALERT")
.setContentText("TURN OFF the multi plug for lighting safety")
.setContentIntent();
noti.flags = Notification.FLAG_AUTO_CANCEL;
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
nm.notify(0,noti);
}
If you don't want to have an Intent for the Notification, you should create a dummy one
PendingIntent dummyIntent = PendingIntent.getActivity(
getApplicationContext(),
0,
new Intent(),
PendingIntent.FLAG_UPDATE_CURRENT);
and then call setContentIntent(dummyIntent)

AlarmManager setRepeating()

My program is designed to create a repeating alarm that triggers a broadcastreceiver in turn making a notification. The alarm is repeated using a user-entered interval.
For example, if i want to set the alarm to run every 10 seconds, how would I do that?
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 10000, calpendingintent);
Is this right? and my broadcast receiver isn't being called either for some reason.
public static void createAlarms(Context mcontext) {
cal = Calendar.getInstance();
cal.add(Calendar.HOUR, alarmintervalint);
calintent = new Intent(mcontext, AlarmBroadcastReceiver.class);
calpendingintent = PendingIntent.getBroadcast(mcontext.getApplicationContext(), 12345, calintent, 0);
am = (AlarmManager)mcontext.getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 10000, calpendingintent);
}
My broadcastreceiver class is not being called and Im not sure the "setRepeating()" method Im using is set correctly..
Please help!
use this code
AlarmManager alarmMgr;
PendingIntent pendingIntent;
public void startAlarmManager()
{
Intent dialogIntent = new Intent(getBaseContext(), AlarmBroadcastReceiver.class);
alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
pendingIntent = PendingIntent.getBroadcast(this, 0, dialogIntent,PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), 10000, pendingIntent);
}
}
wheather you want to stop alarm
public void stopAlarmManager()
{
if(alarmMgr != null)
alarmMgr.cancel(pendingIntent);
}
Be Remembered dont forget to register Receiver in manifest file
<receiver android:name=".AlarmBroadcastReceiver" >
</receiver>
Use setInexactRepeating() instead of setRepeating(). When you use setInexactRepeating(), Android synchronizes repeating alarms from multiple apps and fires them at the same time.
This reduces the total number of times the system must wake the device, thus reducing drain on the battery. As of Android 4.4 (API Level 19), all repeating alarms are inexact.
Note that while setInexactRepeating() is an improvement over setRepeating(), it can still overwhelm a server if every instance of an app hits the server around the same time. Therefore, for network requests, add some randomness to your alarms
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 30);
long time = cal.getTimeInMillis();
Intent i = new Intent(G.context, BootCompleteReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(G.context, 0, i, 0);
G.alarmManager.set(AlarmManager.RTC_WAKEUP, time, pi);
you can use this. Hope it solves your problem
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY,
AlarmManager.INTERVAL_DAY, pi);

Categories