I am having a reminder application in which i have an alarm manager like this
public class ReminderManager {
private Context mContext;
private AlarmManager mAlarmManager;
public ReminderManager(Context context) {
mContext = context;
mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
}
public void setReminder(Long taskId, Calendar when) {
System.out.println("**********************************remindedrmanager************************" );
Intent i = new Intent(mContext, OnAlarmReceiver.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
}
}
I am getting only one alram even if I set multiple alarm. Is the problem due to some mistake in the above code or is it because of some other mistake.
You have change argument no 2 in line where you declared pending Intent as per below code. Instead specify (int)System.currentTimeMillis() in place of 0
And also android set multiple alarms simultaneosuly
PendingIntent pi = PendingIntent.getBroadcast(mContext,(int)System.currentTimeMillis(), i, PendingIntent.FLAG_UPDATE_CURRENT);
Related
I am using targetSdkVersion 24. I set up an alarm like this:
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("REQUEST_CODE", CHEW_REQ_CODE);
intent.putExtra("CHEW_TEXT", chewText);
PendingIntent pIntent = PendingIntent.getBroadcast(context, CHEW_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, interval, pIntent);
where interval is 15 x 60 x 1000 = 15 min. This alarm is set in a check box in the preferences. On a HTC One running API 23 the alarm goes off as expected. However, when I cancel this alarm by unchecking the preference, the alarm keeps going off. This is my cancel code:
if (alarmMgr != null) {
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("REQUEST_CODE", CHEW_REQ_CODE);
intent.putExtra("CHEW_TEXT", chewText);
PendingIntent pIntent = PendingIntent.getBroadcast(context, CHEW_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.cancel(pIntent);
}
What am I missing?
You will need to hold on to the original PendingIntent object you use in alarmMgr.setRepeating(...) instead of creating a new one. Something like this should help;
PendingIntent startAlarm(Context context){
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("REQUEST_CODE", CHEW_REQ_CODE);
intent.putExtra("CHEW_TEXT", chewText);
PendingIntent pIntent = PendingIntent.getBroadcast(context, CHEW_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval, interval, pIntent);
return pIntent;
}
void stopAlarm(Context context, PendingIntent pIntent) {
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if (alarmMgr!= null) {
alarmMgr.cancel(pIntent);
}
}
Then usage in your class would be something like the following (here I used onPause and onResume of an Activity):
PendingIntent alarmIntent;
#Override
protected void onResume() {
super.onResume();
alarmIntent = startAlarm(this);
}
#Override
protected void onPause() {
super.onPause();
if (alarmIntent != null) {
stopAlarm(this, alarmIntent);
alarmIntent = null;
}
}
HTHs!!!
Thanks to Blehi, I found that the code was not called. The part was this:
if (alarmMgr != null) {
alarmMgr.cancel(chewIntent);
}
AlarmReceived is implemented as Singleton, while the AlarmManager is instantiated in my setAlarm. So alarmMgr was null when the alarm was canceled.
I have an app that allows a user to create a reminder to alert them in the future. The issue I am running into, is that as a user creates more than one reminder, the pending intent only triggers on the latest one created, with the earliest reminder content to display, ie:
Task 1, set for 4pm
Task 2, set for 5pm
Task 3, set for 6pm
No reminder will appear until 6pm, which will display Task 1.
I believe it has to due with the lack of uniqueness of the PendingIntent:
public class ReminderManager {
private Context mContext;
private AlarmManager mAlarmManager;
public ReminderManager(Context context) {
mContext = context;
mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
}
public void setReminder(Long taskId, Calendar when) {
Intent i = new Intent(mContext, OnAlarmReceiver.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
}
}
How can I ensure that each reminder is unique and gets its correct time on time?
You need to provide something other than 0 for the requestCode param. Try making it a unique ID for each request.
I need to trigger two alarms. The first one fires correctly if its just one alarm. If I include the code for the second one, the alarms overlap and the desired functionality is not achieved. My question is do I need two broadcast receivers or I can do it with one?
first alarm:
public void triggerEnable(boolean enableData, int hourInDay, int minInDay) {
Calendar calendar = Calendar.getInstance();
//if (enableData) {
calendar.set(Calendar.HOUR_OF_DAY, hourInDay);
calendar.set(Calendar.MINUTE, minInDay);
// } else {
// calendar.set(Calendar.HOUR_OF_DAY, hourInDay);
// calendar.set(Calendar.MINUTE, minInDay);
// }
calendar.set(Calendar.SECOND, 0);
Intent broadcastIntent = new Intent("com.sang.mobiledata.IntentAction.RECEIVE_CONN_UPDATE");
broadcastIntent.putExtra("FLAG_KEY", enableData);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, pi);
}
broadcast receiver:
#Override
public void onReceive(Context context, Intent intent) {
if(CONN_ACTION.equals(intent.getAction())) {
boolean enableConn = intent.getBooleanExtra("FLAG_KEY", false);
objNetwork.setMobileDataEnabled(context, enableConn);
//what do I do here to have different values for the second alarm?
}
}
}
This can be achieved by using single broadcastreceiver but using pending intents with different ids.
Right now what you are doing is sending multiple pending intents with same ID. Because of this they are overlapping. What you need to do is send another pending intent with a different ID.
First intent
PendingIntent pi = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Second intent
PendingIntent pi = PendingIntent.getBroadcast(this, 1, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Then with the help of alarmManager, fire these pending intents to be received by your broadcastreceiver.
Hope it helps
As Stated in android doc.
If there is already an alarm scheduled for the same IntentSender, it will first be canceled.
I believe you need to set the timing one by one.
You have to create two pending Intents.
Intent alarm1 = new Intent("com.sang.mobiledata.IntentAction.RECEIVE_CONN_UPDATE");
broadcastIntent.putExtra("FLAG_KEY", enableData);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, alarm1 , PendingIntent.FLAG_UPDATE_CURRENT);
Intent alaram2 = new Intent("com.sang.mobiledata.IntentAction.RECEIVE_CONN_UPDATE");
broadcastIntent.putExtra("FLAG_KEY", enableData);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, alaram2 , PendingIntent.FLAG_UPDATE_CURRENT);
Then you have to register two broadcast receivers.
private static BroadcastReceiver alarm1= null;
private static BroadcastReceiver alaram2= null;
alarm1= new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
if(CONN_ACTION.equals(intent.getAction())) {
boolean enableConn = intent.getBooleanExtra("FLAG_KEY", false);
objNetwork.setMobileDataEnabled(context, enableConn);
}
}
alaram2=new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent arg1) {
//put your code for the second alarm here
}
Try this. I am sure this will work.
I need help. Im new to android coding.
I have made task list, which I want to do specific things at time written in task.
Here is my task item
private long id;
private int mon;
private int tues;
private int wednes;
private int thurs;
private int fri;
private int satur;
private int sun;
private int profile;
Where I have days (monday,tuesday etc) which holds amount of minutes (for 10:00 its 600).
Following some tutorials I have alarm reciever
public class AlarmReciever extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Intent newIntent = new Intent(context, AlarmActivity.class);
newIntent.putExtra("profile", message);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
Its still unedited...
And then there is code which calls to make new tasks in alarm manager
// get a Calendar object with current time
Calendar cal = Calendar.getInstance();
// add 5 minutes to the calendar object
cal.add(Calendar.MINUTE, 5);
Intent intent = new Intent(ctx, AlarmReceiver.class);
intent.putExtra("alarm_message", "O'Doyle Rules!");
// In reality, you would want to have a static variable for the request code instead of 192837
PendingIntent sender = PendingIntent.getBroadcast(this, 192837, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
I dont understand how to specify in calendar, that I need new task repeating (for example) every monday at 10:00, and that when this happens, it calls new function, giving it "profile" variable to work with.
private void setProfile(Integer profile)
{
// Doing things with profile
}
take a look at the following code:
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent2 = new Intent(context, SampleAlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent2, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// Set the alarm's trigger time to item hour
calendar.set(Calendar.HOUR_OF_DAY, NuevoItemActivity.hora.getCurrentHour());
calendar.set(Calendar.MINUTE, NuevoItemActivity.hora.getCurrentMinute());
// Set the alarm to fire , according to the device's clock, and to repeat once a day.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, (PendingIntent) alarmIntent);
As you can see in last line, you are able to indicate AlarmManager.INTERVAL_DAY to repeat the PendingIntent.
I want cancel AlarmManager which define a service,in this service might start a new AlarmManger or cancel alarm that defined before.And I know the params pendingintent in alarmManager.cancel(PendingIntent),must be the same.compare with filterEquals(Intent other)
but It still not work.cancel failed.
here is my code
public class GetRoundStroe {
private Store[] stores;
private Context mContext;
public GetRoundStroe(Context mContext) {
this.mContext = mContext;
}
public Store[] getStores() {
if (ComCommand.haveInternet(mContext)) {
start_am_normal();
} else {
start_am_silence();
}
return stores;
}
public Store[] start_am_silence() {
long firstTime = SystemClock.elapsedRealtime();
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
if (AlarmHolder.mAlarmNormal != null) {
am.cancel(AlarmHolder.mAlarmNormal);
}
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, TestSwitch.getInstance().getSilence_time(), AlarmHolder.mAlarmSilence);
return null;
}
public Store[] start_am_normal() {
long firstTime = SystemClock.elapsedRealtime();
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
if (AlarmHolder.mAlarmSilence != null) {
MyLog.e(GetRoundStroe.class,"AlarmHolder.mAlarmSilence"+AlarmHolder.mAlarmSilence+"");
am.cancel(AlarmHolder.mAlarmSilence);
}
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, TestSwitch.getInstance().getNormal_time(), AlarmHolder.mAlarmNormal);
return null;
}
private static final class AlarmHolder {
static final PendingIntent mAlarmSilence = PendingIntent.getService(ApplicationContext.getInstance(),
0,
new Intent(ApplicationContext.getInstance(), GetRoundSilenceService.class),
0);
static final PendingIntent mAlarmNormal = PendingIntent.getService(ApplicationContext.getInstance(),
0, new
Intent(ApplicationContext.getInstance(), GetRoundNormalService.class),
0);
}
}
GetRoundSilenceService and GerRoundNormalService invoke start_am_normal() or start_am_silence; Anyone could help me? thanks
myIntent = new Intent(SetActivity.this, AlarmActivity.class);
pendingIntent = PendingIntent.getActivity(CellManageAddShowActivity.this,
id, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
pendingIntent.cancel();
alarmManager.cancel(pendingIntent);
These lines of code surely can help you remove/cancel the pending intent and alarm.
The main thing that you will need is:
Create pending intent with the same id and appropriate intent FLAG.
Cancel that pending intent.
Cancel the alarm using alarm manager.
#MKJParekh answer is correct, however I would like to add more information so that we all know what will work and what will not.
Lets say on activityA you create and set the AlarmManager to open activityC in 30 seconds, then on some other activity which can be any, we want to cancel that AlarmManager. Thus, we would do the following;
in activityA we create and set the AlarmManager;
//activityA
Intent myIntentA = new Intent(actvityA.this, activityB.class)
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent myPendingIntent = PendingIntent.getActivity(activityA.this, 0, myIntentA, PendingIntent.FLAG_ONE_SHOT);
//Calendar with the time we want to fire the Alarm
Calendar calendar = Calendar.getInstance(); // Get Current Time
calendar.add(Calendar.SECOND,30); //Fire Alarm in 30 seconds from Now.
((AlarmManager)getSystemService(ALARM_SERVICE)).setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), myPendingIntent);
in Another Activity some time later we want to cancel such AlarmManager created in activityA which we have no access to. Lets call this current activity activityZ;
//activityZ
Intent myIntentZ = new Intent(activityZ.this, activityB.class);
PendingIntent pendingIntentZ = PendingIntent.getActivity(activityZ.this, 0, myIntentZ, PendingIntent.FLAG_ONE_SHOT);
((AlarmManager)getSystemService(ALARM_SERVICE)).cancel(pendingIntentZ);
Some important points,
The context we provide in activityA in new Intent(context) and getActivity(context) are the same, however they do not have to match the activity from where we are canceling the AlarmManager, in this case activityZ has another context.
The class we want to open with the AlarmManager has to be the same in both activities new Intent (context, activityB.class), the requestCode which is an int must be the same, I used 0 for this example. Finally the flag has to be the same in both activities PendingIntent.FLAG_ONE_SHOT.
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); was used because PendingIntent.getActivity requires it if we are starting an activity outside of a context of an existing activity.