Android AlarmManager: how to use it to STOP an Activity - android

In my App I use an AlarmManager to start an Activty at a certain days of the week and at a certain hour.
So I have an AlarmManager that an MON, TUE, WED.. at 12:00 fires off an Activity...
Now, the point is that I need to stop the same activity at a precise time (again using the AlarmManager if it is possible).
Please how do I achieve that: AlarmManager to STOP an Activity?

you can register a broadcastReceiver in that activity. if you wanna stop it, send a broadcast notification to that Activity, and trigger relevant callback function to finish the activity.

As Pankaj said use services and u can unregister the broadcast reciever
public void stopService() {
Log.d("TAG", "CancelAlarm Start");
Intent intent = new Intent(context, PullNotification.class);
PendingIntent sender = PendingIntent
.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}

Related

Stopping a repeating alarm from a BroadcastReceiver - is it possible?

I have an AlarmManager that sets a repeating alarm for the purpose of periodically querying a server.
private AlarmManager alarmManager;
private PendingIntent pendingIntent;
alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent photosIntent = new Intent(this,AlarmReceiver.class);
//startService(photosIntent);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),0,photosIntent,0);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime(),
10000, pendingIntent);
And I start an IntentService within the AlarmReceiver's onReceive() method. AlarmReceiver is a BroadcastReceiver. Here is the onReceive() method:
#Override
public void onReceive(Context context, Intent intent) {
Intent photosIntent = new Intent(context,JSONPhotosParser.class);
context.startService(photosIntent);
}
Now, this is something crazy I want to do, as it is not very practical. Is there any way I can stop my AlarmManager from within the BroadcastReceiver. I can also think of a practical scenario where such an action would be required. Say I am querying the status of a network connection using ConnectivityManager and if a connection exists I would start an IntentService that queries a server (which is my current scenario). If network status returns false, I would like to stop the repeating alarm set by the AlarmManager.
Is this possible within the BroadcastReceiver ? I understand that an AlarmManager can be removed using cancel(PendingIntent operation). But how do I create PendingIntent inside the BroadcastReceiver ?
Any help on this would be most appreciated. From an Android noob.
refer this link :
AlarmManager.cancel (PendingIntent operation)
http://developer.android.com/reference/android/app/AlarmManager.html#cancel%28android.app.PendingIntent%29

AlarmManager still triggering alarm after canceling the associated service and PendingIntent

I have a service which uses PendinIntent and AlarmManager to launch another activity after a fixed period of time.
Here is the relevant code of the service:
Calendar cal = Calendar.getInstance(); //Create a calendar
cal.add(Calendar.MINUTE, 1); //Add the set minutes to the alarm
Intent dialogIntent = new Intent(this, alarmRingLayout.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1234, dialogIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
When the service starts, I also set up a notification which has the a button that can cancel the service incase the user does not want the activity to launch.
On click of the "cancel" button, stopService() is called:
stopService(new Intent(StopPowerNapAlarmService.this, PowerNapAlarmService.class));
onDestroy() has the following code which cancels the notification and calls stopSelf()
It also tries to cancel the PendingIntent and AlarmManager.
The problem is that the Activity opens up even after after onDestroy is called. I believe the PendingIntent and/or AlarmManager are not getting canceled.
Here is the code for onDestroy():
#Override
public void onDestroy() {
Toast.makeText(this, "Alarm Finished", Toast.LENGTH_SHORT).show();
CancelNotification(this, 0);
//Cancel the pending intent and AlarmManager
Intent myntent = new Intent(PowerNapAlarmService.this, PowerNapAlarmService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
1234, myntent, PendingIntent.FLAG_UPDATE_CURRENT);
pendingIntent.cancel();
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.cancel(pendingIntent);
stopSelf();
}
What is going wrong over here?
What is going wrong over here?
Your Intent objects are different, so your PendingIntent objects are different. This, in turn, means that you are working with different alarms. The first Intent points to an alarmRingLayout.class activity. The second Intent points to a BroadcastReceiver oddly named PowerNapAlarmService.
If you want to cancel() the alarmRingLayout alarm, create an activity PendingIntent for alarmRingLayout, and use that with cancel().
Also, please get rid of stopSelf() in onDestroy(), as that is not needed and could conceivably cause problems.

Android AlarmService repeating alarm repeats once more after cancel is called

First off,this site is great and everyone is so helpfull. This is my first post so forgive me if i have ommited anything.
I create an alarm like so:
private void startLocation() {
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyWeatherUpdateService.class);
PendingIntent service = PendingIntent.getService(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
alarm.setRepeating(AlarmManager.RTC, SystemClock.elapsedRealtime() + (60 * 1000),
Long.parseLong(prefs.getString("listpref", "60000")), service);
}
In this method which is called inside a fragment, context is from getApplication (), listpref is a string update interval in milliseconds.
I cancel it by:
public void endLocation() {
Intent i = new Intent(context, MyWeatherUpdateService.class);
PendingIntent service = PendingIntent.getService(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
alarm.cancel(service);
}
Ensuring that the intent/pending intent is the same.
Now i have 2 issues:
1) the alarm fires almost imediately after creation, even though i tell it to start after 1min.
2) when i call cancel, the alarm fires once more before the alarm is cancelled.
With question 1) why does the alarm fire so soon? And with 2) is this working as intended or should the alarm cancel immediately like i want it to.
If i have not supplied enough info, ill add more code if required.
Thanks in advance.
the alarm fires almost imediately after creation, even though i tell it to start after 1min
That is because you are using RTC with an elapsedRealtime() starting time. Those need to match. The simplest solution is to switch to ELAPSED_REALTIME.
when i call cancel, the alarm fires once more before the alarm is cancelled.
Try replacing PendingIntent.FLAG_CANCEL_CURRENT with 0, at least in the PendingIntent for your cancel() call.

AlarmManager only lets one Service through when used with setRepeating in Android

I've been struggling with this for a couple of days. What I want to do is run a service periodically, about 2-3 minutes apart. I have an Activity that is responsible for the interface and setting up the first alarm.
The alarm is configured by a BroadcastReceiver which looks like this:
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String message = "Alarm worked";
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
setAlarm(context);
}
public void setAlarm(Context context){
AlarmManager am = (AlarmManager) context.
getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Receiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent dailyUpdater = new Intent(context, DiscoveryService.class);
context.startService(dailyUpdater);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ (1000 * 30) , pi);
}
}
I've tried using setRepeating for AlarmManager, but it still has the same effect. What happens is that the AlarmManager works how it should, it fires an Intent which the receiver gets and executes onReceive periodically, as it should. However, it executes the service only the first time. After the first time, the alarms still go off, but the service is not executed.
I read some threads from people with similar problems, and one of them mentioned that PendingIntent lasts for only one send. Thus, I opted out to setting the alarm every time so I can set pendingIntent flag for updating every time.
I tried making my service an intentService, which is fine, but then my bluetooth scanner inside the service does not work because intentService thread terminates without waiting for my bluetooth discovery to finish.
Anyone have any idea what can help me?
Here is part of my service:
public class DiscoveryService extends Service {
public void onCreate() {
super.onCreate();
Toast.makeText(this, "MyAlarmService.onCreate()",
Toast.LENGTH_LONG).show();
findEverything();
}
}
EDIT: This is the code that I currently have.
public void onReceive(Context context, Intent intent) {
String message = "Alarm worked";
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
Intent dailyUpdater = new Intent(context, DiscoveryService.class);
context.startService(dailyUpdater);
}
public void setAlarm(Context context){
// get a Calendar object with current time
AlarmManager am=(AlarmManager)context.
getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Receiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
(1000 * 30) , pi);
}
What happens is that the AlarmManager works how it should, it fires an Intent which the reciever gets and executes onReceive periodically, as it should. However, it executes the service only the first time. After the first time, the alarms still go off, but the service is not executed.
You are calling startService() once when you are scheduling the alarm. You are not calling startService() at all from your BroadcastReceiver. Yet you are scheduling the alarm via the BroadcastReceiver. Hence, when the alarm goes off, the service will not be sent a command, because you are not sending it a command.
I read some threads from people with similar problems, and one of them mentioned that PendingIntent lasts for only one send.
That is only if you use FLAG_ONE_SHOT.
Anyone have any idea what can help me?
Call startService() from your onReceive() method, instead of from your setAlarm() method. Also, add in all the WakeLock management logic, since you are using a _WAKEUP alarm and you are not able to use my WakefulIntentService.

Alarmmanager with pending Intent

The code snippet below....
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
///////////Do something////////////////////////
showtext.startScan();
//SEt Alarm
Intent intent = new Intent(this, TextReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+9000, pi);}
And my Receiver :
TextReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
///Show text/////
}
}
The thing is that when I run the program after 9sn, I am getting an error that "The app stopped unexpectedly". Why I get this error?
My goal is to show the text every 9sn. What is the correct usage of AlarmManager in the main activity
OR Should I set alarm in the BroadcastReceiver ?
Which one does makes sense: am.setRepeating or am.set in terms of my goal?
**Edit: How can I change my alarm code to run in the Broadcast Receiver ? **
//try this
AlarmManager am=(AlarmManager)getApplicationContext getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),(9 * 1000), pendingIntent);
Never, ever use FLAG_CANCEL_CURRENT with PendingIntents that are set as alarms.
What happens is that you wind up canceling the validity of the PendingIntent currently held by the alarm manager, and this means that the alarm manager can no longer tell that any newly-set alarm matches that old PendingIntent. You wind up with the old (invalid) alarm still registered along with your new one. If you keep doing this you can wind up with hundreds (or more!) stale alarms registered in the system, none of which will actually do anything but which are taking up memory and CPU.

Categories

Resources