I am trying to stop the alarmManager in the MainActivity from the onBackPressed() method in the Map activity. I have tried the code below but the alarmManager is not being stoped and still firing. How can I fix it?
Code in the MainActivity:
Intent intent = new Intent(MainActivity.this, GetLLRD.class);
intent.putExtra("json_data", json);
PendingIntent pendingIntent = PendingIntent.getService(
getApplicationContext(), 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
alarm.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 20 * 1000, pendingIntent);
startService(intent);
Code in the Map Activity:
#Override
public void onBackPressed() {
Intent intent = new Intent(Map.this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getService(
getApplicationContext(), 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
}
u problem is u use two different classes for intent to create and stop alarm:
Intent intent = new Intent(context,
GetLLRD.class);
Intent intent = new Intent(context,
MainActivity.class);
/** as in source code - new intent constructor */
public Intent(Context packageContext, Class<?> cls) {
mComponent = new ComponentName(packageContext, cls);
}
if u want to check if u got the same pending intent as before you can try to use:
Intent.filterEquals(oherIntent);
to cancel alarm you have two options use flag or use the same intent on alarm:
PendingIntent.FLAG_CANCEL_CURRENT
& i advice to make pending intent as final - example:
/**
* create pending intent
*/
final PendingIntent pIntent(Intent alarmIntent) {
// Create a PendingIntent to be triggered when the alarm goes off
return PendingIntent.getBroadcast(getApplicationContext(), AlarmReceiver.REQUEST_CODE,
alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
/**
* cancel alarm
*/
public void cancelAlarm(Intent alarmIntent, Context context) {
try {
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
/** use flag cancel here */
PendingIntent pIntent = PendingIntent.getService(context, AlarmReceiver.REQUEST_CODE, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
/** cancel alarm */
alarm.cancel(pIntent);
} catch (Exception e) {
// handle exception here
}
}
why to make pending intent final ?
because to cancel alarm u need:
Create pending intent with the same id and appropriate intent FLAG.
(to get reference to current pending intent)
PendingIntent.getBroadcast(context, REQUEST_CODE, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Cancel that pending intent.
PendingIntent.cancel();
Cancel the alarm using alarm manager.
AlarmManager.cancel(PendingIntent);
A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.
if you are using activity, use
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
12345, intent,0);
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 schedule Alarm from Activity like.
private AlarmManager mAlarmManager;
mAlarmManager = (AlarmManager) ACT_ActiveSession.getAppContext()
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(mContext, LocalNotification.class);
intent.putExtra("alertBody", "");
intent.putExtra(K.SESSIONID, "");
intent.putExtra("TIME", "");
intent.putExtra("BATCHNO","");
intent.putExtra("REQUEST_CODE", "");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
ACT_ActiveSession.getAppContext(), REQUEST_CODE, intent, 0);
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, finishTime,
pendingIntent);
// alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, finishTime,
// (1 * 1000), pendingIntent);
intent.putExtra("",""); only used for some task on BroadcastReceiver
And Cancel Alarm From Fragment
private AlarmManager mAlarmManager;
mAlarmManager = (AlarmManager) mActivity
.getSystemService(Context.ALARM_SERVICE);
Intent updateServiceIntent = new Intent(mActivity,
ACT_Home.class);
PendingIntent pendingUpdateIntent = PendingIntent.getBroadcast(
mActivity, REQUEST_CODE,
updateServiceIntent, 0);
pendingUpdateIntent.cancel();
// Cancel alarms
if (pendingUpdateIntent != null) {
mAlarmManager.cancel(pendingUpdateIntent);
Log.e("", "alaram canceled ");
} else {
Log.e("", "pendingUpdateIntent is null");
}
But Alarm Manager is not cancelled.
Here i change mActivity = MyActivity's static getApplicationContext(); and also change different Flags and different Context.
Also I refer many answer. But doesn't work any code. Link1 Link2 Link3
please give me solution as soon as possible.
and apologize for my bad English.
You create the alarm using this Intent:
Intent intent = new Intent(mContext, LocalNotification.class);
But you try to cancel it using this Intent:
Intent updateServiceIntent = new Intent(mActivity, ACT_Home.class);
These Intents do not match, so the cancel does nothing. If you want to cancel the alarm you need to use an Intent in the cancel call that matches the Intent you used to schedule the alarm.
I have created a BroadCastReceiver which schedules some events using alarm manager.
In the BroadcastReceiver I am using following code to schedule.
Intent localIntent = new Intent("com.test.sample");
PendingIntent pi = PendingIntent.getBroadcast(context, 0,
localIntent, 0);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + (5 * 60 * 1000),
pi);
Here context comes from the onReceive method of the receiver.
I want to cancel this alarm on receive of other broadcast.
I am aware that alarm can be cancelled by alarmManager.cancel(pi);
However if the alarmanager was set from any other activity that how to get hold of PendingIntent to cancel it?
Thanks
You need to create a new PendingIntent with the same id then pass it as argument in cancelAlarm() method like follows:
To create alarm
int alarmId = 0; /* Dynamically assign alarm ids for multiple alarms */
Intent intent = new Intent(context, AlarmReceiver.class); /* your Intent localIntent = new Intent("com.test.sample");*/
intent.putExtra("alarmId", alarmId); /* So we can catch the id on BroadcastReceiver */
PendingIntent alarmIntent;
alarmIntent = PendingIntent.getBroadcast(context,
alarmId, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
To cancel alarm (in BroadcastReceiverwhitin onReceive(Context context, Intent intent)method)
int alarmId = intent.getExtras().getInt("alarmId");
PendingIntent alarmIntent;
alarmIntent = PendingIntent.getBroadcast(this, alarmId,
new Intent(this, AlarmReceiver.class),
PendingIntent.FLAG_CANCEL_CURRENT);
cancelAlarm(alarmIntent);
I am using the pending intent in activity.
Intent intent = new Intent(this, MyActivity.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 34433,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + (5000), pendingIntent);
here i am going from one activity(MainActivity) to another activity(MyActivity).
but it is not working.
if i try to do it with simple Intent then it works fine.
You have requested a PendingIntent to start a BroadcastReceiver, but you are trying to start an Activity. This can't work.
If you want to start an Activity, instead of this:
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 34433,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
do this:
PendingIntent pendingIntent = PendingIntent.getActivity(this, 34433,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
You can also use broadcast receiver with PendingIntent to start another activity.
create another class for example receiver as sub class of the BroadcastReceiver
public class receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
// code to start another activity
Intent intent = new Intent(context.getApplicationContext(), MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}
and define MyActivity as receiver in android menifest file
and in main activity change this code
MyActivity.class to receiver.class
Intent intent = new Intent(this, receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 34433,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + (5000), pendingIntent);
In my code, I create an alarm as follows:
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent("mypackage.START_MONITORING_SERVICE");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
long timeForNextStart = System.currentTimeMillis() + elapsedTime;
am.set(AlarmManager.RTC_WAKEUP, timeForNextStart, pi);
To cancel the alarm I do this:
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent("mypackage.START_MONITORING_SERVICE");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
am.cancel(pendingIntent);
My question is whether this is the correct way to cancel ALL alarms of the same intent. The docs say:
Remove any alarms with a matching Intent. Any alarm, of any type,
whose Intent matches this one (as defined by filterEquals(Intent)),
will be canceled.
I'm not exactly sure what defines a "matching intent". If I create multiple alarms with the above code and then peform the cancel as shown, will it cancel ALL of the alarms I created?
You should use PendingIntent flag ==> PendingIntent.FLAG_CANCEL_CURRENT fourth parameters create pendingIntent instance method.
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
Try this
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent updateServiceIntent = new Intent(context, MyPendingIntentService.class);
PendingIntent pendingUpdateIntent = PendingIntent.getService(context, 0, updateServiceIntent, 0);
// Cancel alarms
try {
alarmManager.cancel(pendingUpdateIntent);
} catch (Exception e) {
Log.e(TAG, "AlarmManager update was not canceled. " + e.toString());
}
My question is whether this is the correct way to cancel ALL alarms of
the same intent?
I dont know if you aware of requestCode should be unique in for each pendingIntent for following syntax
public static PendingIntent getService (Context context, int requestCode, Intent intent, int flags)
I'm not exactly sure what defines a "matching intent".
Each pending intent map with its provided intent to trigger and each request code map with that intent .
We can say it can be same requestcode for two different pendingIntent which ideally having two different intents .
Remember , here if PendingIntent have a same requestCode for a same intent then it can be override or cancel according to int flags
If I create multiple alarms with the above code and then peform the
cancel as shown, will it cancel ALL of the alarms I created?
To create a multiple alarm you have to give a different requestCode with the same intent .
If you want to cancel those created alarm then you have to cancel them according requestCode
For example
To Create :
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
For (int i= 0 ; i <5 ; i++){
PendingIntent contentIntent = PendingIntent.getBroadcast(TaskReminder.this, i,
new Intent(),PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, timeForNextStart, contentIntent);
}
To cancel :
For (int i= 0 ; i <5 ; i++){
//Note here ' i ' is the requestCode which map each pendingIntent with there provided intent
PendingIntent contentIntent = PendingIntent.getBroadcast(TaskReminder.this, i,
new Intent(),PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(contentIntent);
}