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.
Related
I want my notification to cancel it's own repeating alarm. However, I don't know how to pass pendingIntent (to cancel it later) before it is even created.
Alarms sets here:
public class Schedule extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wakeLock.acquire();
//next is notification code. //
...
//create intent.
Intent notificationIntent = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context,
NOTIFY_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
...
////
wakeLock.release();
}
public void setAlarm(Context context) {
...
Intent intent = new Intent(context, Schedule.class);
intent.putExtra("DELAY", delay);
intent.putExtra("NOTIFICATION_ID", id);
intent.putExtra("TITLE_TEXT", titleText);
intent.putExtra("BIG_TEXT", bigText);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000 * 60 * delay, 1000 * 60 * delay, pendingIntent);
}
}
The key problem is that I want to cancel the repeating alarm on notification click (intent in onRecieve method), but canceling alarms requires pendingIntent, which notification is a part of. Any way to cheat the system?
Use AlarmManager.cancel() to cancel the specific alarm and use same PendingIntent that was used to create the alarm. Of course, you should use same requestCode(NOTIFY_ID) that was used before.
Try this:
Intent intent = new Intent(this, Schedule.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, NOTIFY_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Add this code portion into your MainActivty's onCreate() method as your notification will intent to MainActivity when click on it from notification panel.
Hope this will help~
I am facing this really weird problem. I have made a working alarm system. But when I delete the alarm, it calls it.
AlarmBuddy.java (Working class to set original alarm)
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, m-1);
calendar.set(Calendar.DAY_OF_MONTH, d);
calendar.set(Calendar.HOUR, 8);
calendar.set(Calendar.MINUTE, repeat%60);
final Intent myIntent = new Intent(this.context, AlarmMiddle.class);
myIntent.putExtra("name", name);
myIntent.putExtra("id", repeat);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
super.onBackPressed();
PendingIntent pending_intent = PendingIntent.getBroadcast(AlarmBuddy.this, repeat, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pending_intent);
ListRecord.java THE FLAW
public Boolean cancelAlarm(int id){
Intent myIntent = new Intent();
PendingIntent.getBroadcast(context, id, myIntent,
PendingIntent.FLAG_CANCEL_CURRENT).cancel();
return false;
}
This function is to cancel the alarm. This has some problem to say this again:
The code can SET AND CALL an alarm. But when I delete it from a DIFFERENT class, it immediately calls the alarm. Maybe I am just a noob. Or maybe this is an unsolvable problem.
This is working for me at all in my application see link
Intent intent = new Intent(getBaseContext(), Your_Service.class);
PendingIntent pendingIntent = PendingIntent.getService(getBaseContext(), reqcode, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
To cancel the alarm, you need to use the same PendingIntent as you used to set it. You should also tell the AlarmManager to cancel the alarm as well as canceling the PendingIntent. Try this:
public Boolean cancelAlarm(int id) {
Intent myIntent = new Intent(context, AlarmMiddle.class);
PendingIntent pending_intent = PendingIntent.getBroadcast(context, id, myIntent,
PendingIntent.FLAG_NO_CREATE);
if (pending_intent != null) {
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pending_intent);
pending_intent.cancel();
}
return false;
}
I'm testing AlarmManager to use in my app, and it is firing my Broadcast Receiver immediately when I want it to fire after 1 minute. The code is below:
public class SetMealTimersActivity extends Activity {
PendingIntent pi;
BroadcastReceiver br;
AlarmManager am;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_meal_timers);
br = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
Toast.makeText(c, "Ready to Go!", Toast.LENGTH_LONG).show();
}
};
registerReceiver(br, new IntentFilter("com.ian.mealtimer"));
pi = PendingIntent.getBroadcast(this, 0, new Intent(
"com.ian.mealtimer"), 0);
am = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
am.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() +
60 * 1000, pi );
}
try :
am.set(AlarmManager.RTC_WAKEUP,
Calendar.getInstance().getTimeInMillis()+60*1000, pendingIntent);
it is working for me.
If using an exact alarm, make sure it's time is in the future. Otherwise it will fire immediately.
Try changing SystemClock.elapsedRealtime() to System.currentTimeMillis() and AlarmManager.ELAPSED_REALTIME_WAKEUP to AlarmManager.RTC_WAKEUP.
Try to use AlarmManager.setExact(int, long, PendingIntent) if you use Android API > 18 or compile with API < 19, because the time management for this methods changed with API 19. Maybe that helps. Read the documentation for more information.
make id for pendingIntent as this
pendingIntent = PendingIntent.getActivity(this, 999123266,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
All example
public void setAlarm_sat(int dayOfWeek1) {
cal1.set(Calendar.DAY_OF_WEEK, dayOfWeek);
Intent intent = new Intent(this, RemmemberActivity.class);
pendingIntent = PendingIntent.getActivity(this, 999123266,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Long alarmTime = cal1.getTimeInMillis();
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP,
alarmTime,7*24 * 60 * 60 * 1000,
pendingIntent);
// am.set(AlarmManager.RTC, cal1.getTimeInMillis(), pendingIntent);
}
private void scheduleAlarms(Context context) {
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intentOnAlaramReceiver = new Intent(context, OnAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentOnAlaramReceiver, 0);
String listOfIntervalConnection = Utils.getStringFromProperties(context, Properties.SP_LIST_OF_ENABLE_INTERVAL_CONNECTIONS, Properties.ENABLE_AFTER);
long enableAfter = DateUtils.MINUTE_IN_MILLIS * Long.parseLong(listOfIntervalConnection);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + enableAfter, enableAfter, pendingIntent);
}
and i try to cancel alarm like
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intentOnAlaramReceiver = new Intent(context, OnAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentOnAlaramReceiver, 0);
alarmManager.cancel(pendingIntent);
but sometimne is canceled sometimes still working. Why and how? What can i do?
You are using different instances of Intent in the PendingIntent when starting the service and while canceling it.
set the service intent as an instance variable and use it in both the starting and canceling of the service.
Try to use PendingIntent.FLAG_UPDATE_CURRENT instead of 0; Like this:
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentOnAlaramReceiver, PendingIntent.FLAG_UPDATE_CURRENT);
I must create an AlarmManager that repeating every seconds, I use this code
Intent in = new Intent(context,Tempo_Indietro.class);
in.putExtra("id_widget", appWidgetIds[i]);
PendingIntent pi = PendingIntent.getActivity(context, 0, in, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, pi);
but it don't start...why ??
To start a Scheduled Activity: you can use like:
Step1: Setting for AlarmManager
Intent intent =new Intent(context,AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, in, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManger.RTC_WAKEUP,System.currentTimeMillis(), 1000, pi);
Step2: creating a BroadcastReceiver
public class AlarmReceiver extends BroadcastReceiver {
//override onReceive(Context, Intent) method
#Override public void onReceive(Context context, Intent intent)
{
//.........
Intent i = new Intent(context,Tempo_Indietro.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
//..........
}
}
Note: Don’t forget to include the newly created activity, receiver in the AndroidManifest.xml file.