Multiple alarms are getting fired after reboot in android through broadcast receiver - android

I am making a notification application and for that i am using scheduled alarms for running the notifications using Broadcast receiver class and i am prompting user to select from daily or hourly notifications and i am defining both alarms in the same receiver under the same function and it is working fine but the problems comes when i restart my device,when i restart it both the alarms (daily and hourly) are getting triggered when i am only setting one for example if i set an alarm for 11:20 A.M and restart my device the hourly one and this 11:20 one both are getting triggered,i want that when i restart my device only the alarm which was selected before the device boot only gets triggered.
My receiver class:-
public class alarmreceiver extends BroadcastReceiver {
int id=0;
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm running", Toast.LENGTH_SHORT).show();
start(context,id);
}
static void start(Context context,int id) {
Intent intent = new Intent(context, notification_receiver.class);
PendingIntent pendingintent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (id==1) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR, 11);
calendar.set(Calendar.MINUTE, 9);
calendar.set(Calendar.AM_PM, Calendar.AM);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingintent);
}
else
if (id==2) {
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), 60 * 1000
, pendingintent);
}
}
I am calling this function under button click listener like this:-
For daily notifications:-
alarmreceiver.start(getApplicationContext(),1);
For hourly notifications:-
alarmreceiver.start(getApplicationContext(),2);

This code:
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(), 60 * 1000, pendingintent);
sets a repeating alarm that goes off every minute, not every hour!
Also, this code sets an alarm that goes off right now and again every minute. The second argument to setRepeating() is the time of first alarm. You've passed SystemClock.elapsedRealtime() which basically means "now".

Related

Background repeating task with onboot

Hello i want to make a background service to update the data of my app and repeat it once a day, also i want the service to start onboot. I have the following code:
public class OnBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Create Intent
context.startService(new Intent(context, BackgroundServiceHandler.class));
}
}
I have a settings menu so the user can choose the hour of the repeating alarm.
How can i reset the time of the alarmmanager? Where i have to put the code of the alarm manager? Do i have to use service or intentservice? How to check if service is running?
Alarm manager code:
Intent intent = new Intent(MainActivity.this, AlarmService.class);
intent.putExtra("i", 3);
PendingIntent pi = PendingIntent.getService(MainActivity.this, 9, intent, 0);
// every day at 9 am
Calendar calendar = Calendar.getInstance();
// if it's after or equal 9 am schedule for next day
if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 9) {
calendar.add(Calendar.DAY_OF_YEAR, 1); // add, not set!
}
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pi);
How can i reset the time of the alarmmanager?
How to edit/reset Alarm Manager?
Where i have to put the code of the alarm manager?
For example you can place that code in static method and call it from place where user set time and from OnBootReceiver. How to implement class which will receive event OnBoot please check that answer.
Do i have to use service or intentservice?
Service vs IntentService
How to check if service is running?
Check if service is running on Android?

Setting Alarm Manager in Android

I am following Android developers documentation and some other tuts to create an Alarm manager which fires and wakes up the CPU at 4pm everyday, following is my code:
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
BroadcastReceiver br;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 16);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
public void setup() {
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
Toast.makeText(c, "Rise and Shine!", Toast.LENGTH_LONG).show();
//Invoke the service here Put the wake lock and initiate bind service
}
};
registerReceiver(br, new IntentFilter("com.testrtc") );
alarmIntent = PendingIntent.getBroadcast( this, 0, new Intent("com.testrtc"),
0 );
alarmMgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}
}
Manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
However I dont get any errors, but the alarm (Toast message) wont fire.
EDIT from the developer docs:
RTC examples
Here are some examples of using RTC_WAKEUP.
Wake up the device to fire the alarm at approximately 2:00 p.m., and repeat once a day at the same time:
// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
This one for set Repeating, says that if I want my alarm to fire at 8:30 and then repeat after each 20 minutes, however I just want to fire my alarm at a specific time but I dont want to repeat it.
Wake up the device to fire the alarm at precisely 8:30 a.m., and every 20 minutes thereafter:
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);
// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 20, alarmIntent);
Decide how precise your alarm needs to be
Choosing the alarm type is often the first step in creating an alarm. A further distinction is how precise you need your alarm to be. For most apps, setInexactRepeating() is the right choice. When you use this method, Android synchronizes multiple inexact repeating alarms and fires them at the same time. This reduces the drain on the battery.
For the rare app that has rigid time requirements like yours, the alarm needs to fire precisely at 4:00 p.m. everyday then use setRepeating().
Reference: Decide how precise your alarm needs to be
Solution :
alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// Set the alarm to start at approximately 4:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 16);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000*60*60*24, alarmIntent);
Edited Testing : (Fire alarm at every 10seconds)
alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(),
1000*10, alarmIntent);
Conclusion :
setup() method was not called before dealing with alarms.
Update for API 19+
setRepeating is inexact when targeting api level 19 or higher. For exact repating you can now use setExact() and manage repeating yourself.
reference: AlarmManager documentation
Instead of using setInexactRepeating() I suggest you to use setRepeating()
from the docs,
setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
Schedule a repeating alarm that has inexact trigger time requirements; for example, an alarm that repeats every hour, but not necessarily at the top of every hour.
setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
Schedule a repeating alarm.
Documentation is quite clear:
public void setInexactRepeating (...)
triggerAtMillis time in milliseconds that the alarm should first go
off, using the appropriate clock (depending on the alarm type). This
is inexact: the alarm will not fire before this time, but there may be
a delay of almost an entire alarm interval before the first invocation
of the alarm.
so to my understanding but there may be a delay of almost an entire alarm interval means you may have one day delay, because u use AlarmManager.INTERVAL_DAY.
set minutes and seconds also to calendar ..
calendar.set(Calendar.HOUR, 16); // At the hour you wanna fire
calendar.set(Calendar.MINUTE, 0); // Particular minute
calendar.set(Calendar.SECOND, 0);
and use
alarmManager.setRepeating(AlarmManager.RTC,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
alarmIntent);
I had your same problem (usually is an Huawei issue) and I resolved by enabling the app in the PowerManager or Protected Apps.
Try to create a receiver that extends WakefulBroadcastReceiver:
public class MyReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myService = new Intent(context, MyService.class);
context.startService(myService);
}
}
In your service, you can put your toast, or try to write a log in a file to be sure that it works. Then, in your activity:
Intent myAlarm = new Intent(context.getApplicationContext(), MyReceiver.class);
PendingIntent recurringAlarm = PendingIntent.getBroadcast(context.getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarms.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), 4 * 1000 * 60, recurringAlarm);
// Alarm every 4 minutes

Alarm manager triggered immediately

Hi I am currently working with AlarmManager. I have written a code given below. As per code the AlarmManager should be triggered after 10 Sec, but here in my code the alarm manager triggers immediately. Please help.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long timeOrLengthofWait = 10000;
Intent intentToFire = new Intent(this, AlarmReciever.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intentToFire, 0);
alarmManager.set(alarmType, timeOrLengthofWait, alarmIntent);
}
}
And My AlarmReciever Class
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String phoneNumberReciever="5556";
String message="Alarm Triggered";
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumberReciever, null, message, null, null);
Toast.makeText(context," A message has been sent", Toast.LENGTH_LONG).show();
Log.d("Alarm ", "Alarm Has been triggered and sms send");
}
}
I have Already added required permissions in manifest.
You are using an alarm type of ELAPSED_REALTIME_WAKEUP. That means that the second parameter to set() must be the number of milliseconds from now, where now is expressed as SystemClock.elapsedRealtime().
If your goal is to have this occur 10000 milliseconds from the time you make the set() call, that set() call should be:
alarmManager.set(alarmType, SystemClock.elapsedRealtime()+timeOrLengthofWait, alarmIntent);
If you are creating PendingIntent of an alarm for past time it will be fired immediately. Example - Schedule alarm for today 8AM but executing code around 11AM will fire immediately.
Solution:
cal.add(Calendar.DATE, 1);
long delay = 24 * 60 * 60 * 1000;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), delay,pendingIntent);`
This will fire the event on next day at specified time (i.e 8AM);

In android, is it possible to use more than one AlarmManager with different repeat values in a single application?

I'm developing an application for mobile and tablet using android 2.3**
I want to do some operations namely Operation-A and Operation-B. Both perform some pocess.
I want to repeat the Operation-A and Operation-B is performed every 1 hour time interval
Operation-A is performed before the 10 minutes of Operation-B
Operation-B is performed when the time is 0.00,1.00,2.00,3.00,....,23.00 (I'm using railway time. So it is not confused for am or pm).
Operation-A is performed when the time is 0.50,1.50,2.50,3.50,....,23.50
The above scenarios is possible in android or not.
All are give your ideas for the above scenarios.
I'm planning to use AlarmManager. AlarmManager is android system service. It is used to notify the application every 1 hour.
I plan to use an AlarmManager for Operation-A and another AlarmManager for Operation-B.
My doubt is ,In android is it possible to use more than one AlarmManager with different repeat values in a single application?
All your ideas are welcome.
Yes this task will done with help of AlarmManager with reperating functionality. First you need to create two receiver class which will receive events . and then need to setup repeating alarm .
private void setAlarm1()
{
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.HOUR, 1);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000*60*60, pendingIntent);
}
private void setAlarm2()
{
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, 50);
Intent intent = new Intent(this, AlarmReceiver_1.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000*60*50, pendingIntent);
}
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
public class AlarmReceiver_1 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
In menifest, you need to declare the classes as below.
<receiver android:name=".AlarmReceiver" />
<receiver android:name=".AlarmReceiver_1" />

My Recurring Task doesn't get called

I am trying to use AlarmManager to accomplish a recurring task. I am using setInexactRepeating() and have set the interval to every 15 minutes (just for testing purposes) however, it doesn't seem to be working. Any ideas?
Here's my code:
AlarmReceiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.w("CacheCrusader", "Recurring Job: Clearing Cache");
}
}
Setter
private void setRecurringAlarm(Context context) {
Calendar updateTime = Calendar.getInstance();
updateTime.set(Calendar.HOUR_OF_DAY, 20);
updateTime.set(Calendar.MINUTE, 15);
Intent downloader = new Intent(context, AlarmReceiver.class);
PendingIntent recurringDownload = PendingIntent.getBroadcast(context,
0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) getSystemService(
Context.ALARM_SERVICE);
alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP,
updateTime.getTimeInMillis(),
AlarmManager.INTERVAL_FIFTEEN_MINUTES, recurringDownload);
}
Code that Sets the Setter
Context context = getApplicationContext();
setRecurringAlarm(context);
Android Manifest Declaration
<receiver android:name=".receiver.AlarmReceiver"></receiver>
No errors are generated in the logcat... the alarm just never fires.
Well, it's inexact so... If you set it the interval to 15 mins, you have to wait for at least half an hour to be sure it has/has not fired. After the starting time you have set (20:15). Try it out with something like 1 min interval for testing. And, if you need a more reliable schedule, use setRepeating(), or possibly set() where each alarm invocation registers the next one.

Categories

Resources