I am building an app that needs to perform an action at a specific date and time and put a notification an hour before this task is performed.
I have searched and found that the Alarm Manager class can be used for this purpose but I am not sure how to use it. Also if in a future point to cancel or edit it once the application is closed and reopened.
I have created a SQlite database which stores the information along with the date and time of the event to happen.
Thanks
Google provides a "Scheduler" code sample which does what you want: display a notification at a given time. This sample also shows how to cancel an alarm.
Edit : I've just watched at the sample code again and you are right, the sample doesn't explain how to get the PendingIntent after the app is closed and reopened. The following code creates the PendingIntent if it doesn't exist, and if it already exists, it returns the existing PendingIntent, thanks to FLAG_UPDATE_CURRENT. So you don't have to care if the alarm has already been started or not: just get the Pending intent, and cancel it.
Intent intent = new Intent(context, MyAlarmReceiver.class);
pendingAlarmIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
....
pendingAlarmIntent.cancel();
Related
I'm making an alarm clock app using PendingIntent and AlarmManager. I know in order to cancel a PendingIntent, you need to recreate it exactly. In my app, much like many other alarm clock apps, there is a list of alarms with a switch to toggle each alarm on/off. When toggled off, I currently recreate the PendingIntent and cancel it using the following:
Intent intent = new Intent(context, MyBroadcastReceiver.class);
String id = this.getId().replaceAll("[^0-9]+", "");
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, id, intent, 0);
alarmIntent.cancel();
The first 3 lines of the code above I believe are unnecessary. When I toggle the alarm, I have access to the custom alarm object which contains the id along with many other details of the alarm. When I'm creating a new alarm, if I store the newly created PendingIntent in the alarm object, I can have access to the PendingIntent used to create the alarm, and just retrieve it and cancel it in 1 line, like this:
this.getPendingIntent().cancel();
I wouldn't have to recreate the intent, get the id, or recreate the PendingIntent from the code shown earlier. This would ultimately save time and resources (not much but it's good practice), so I have a couple questions:
1) Is there anything wrong with storing the PendingIntent in an object and use it later instead of recreating it? It seems like a straightforward answer but I haven't seen anyone do this before.
2) Is there an advantage to recreating the PendingIntent that I'm not aware of?
Thanks!
Is there anything wrong with storing the PendingIntent in an object and use it later instead of recreating it?
Assuming that the underlying Intent doesn't have some massive payload (e.g., Bitmap in an extra), you should be OK.
It seems like a straightforward answer but I haven't seen anyone do this before.
https://github.com/commonsguy/cw-omnibus/tree/v8.7/AlarmManager/Simple, though it's a trivial example.
Is there an advantage to recreating the PendingIntent that I'm not aware of?
It works for cases where you do not have the PendingIntent. Your process does not live forever. If you want to use a cached PendingIntent as an optimization, that's fine, but you need to be in position to create the PendingIntent if it is needed.
I'm creating a reminder application that will show notifications on scheduled time, I'll be storing reminder related data in a database and created the working database and content provider for it, initially I thought of creating an alarm whenever user creates a new reminder, but now I'm not able to fire the notification whenever the alarm triggers, and don't know how can I retrieve the reminder related info from the database, and for repeating reminders like daily or weekly I want to reschedule the same alarm after it triggers as the android developer docs suggested so, but don't have the exact idea of it. Please guide me through this which approach will be better and is there any other better way to do it, and any working demo will be very helpful.
This seems like it is quite a few questions bundled up into one. I would suggest searching for each individual piece as all of the answers to your questions are on this site.
In any case, I copied over an answer on how to set a repeating alarm
AlarmManager am = (AlarmManager) ct.getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(CurrentActivity.this, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ct, 0,intent1, PendingIntent.FLAG_CANCEL_CURRENT);
Date curr=new Date();
curr.setHours(h);
curr.setMinutes(m);
c.setTime(curr);
c.set(Calendar.SECOND, 0);
Calendar c1 = Calendar.getInstance();
am.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
With this code an intent will be fired every day that calls Alarm.class. It is up to you to figure out if you need a service, intent, or anything else as Alarm.class, as it is unclear what the alarm needs to do based on your description.
I have set up a notification that opens a website when you tap it. Here's the part of the code that does it.
Intent resultIntent = new Intent(Intent.ACTION_VIEW);
resultIntent.setData(Uri.parse(m.msg.url));
PendingIntent pending = PendingIntent.getActivity(context, 0,
resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
notif.setContentIntent(pending);
The notifiaction corresponds to a notification in a website, wich also corresponds to a message in that website. So when you tap the (Android) notification, you go to that website. But I also want to remove the (website) notification by sending a GET request. I already have set a method that does that:
m.delete();
However, I can't find a way to execute both actions at once. The intent should open m.msg.url and execute m.delete(). I have searched for information on Intents and Services but I'm new to Android programming and I don't quite understand how it works. I'd really aprecciate any help or guidance.
Thanks for reading.
Create an Activity or Service that performs the GET then immediately starts the activity you really want to start. Use that as the PendingIntent instead.
I am running into a weird situation where I previous has created a pending intent for activity recognition updates
PendingIntent pendingIntent = PendingIntent.getService(mContext, getIntentID(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
my getIntentID code is
private static int getIntentID(){
if(intentID == 0)
return intentID = (int)(System.currentTimeMillis());
return intentID;
}
I did this because I wanted to be sure the id was unique everytime I stop and start my service.
However now when I am in my intentService reading the activities that are being sent I am pretty sure it is not my most recent pendingintent calling making the request. I believe it is from a previous one. However I don't know how to cancel it since I don't know the id from the previous one.
1. Why don't I know the previous id? well when I cancelled the updates via the remove updates I did use my getIntentID which I thought was working correctly however when I stopped my app, started it again but didnt launch the update() code for the activity recognition, I noticed I was still getting activities, when I used the debugger.
Here is my update request
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(getActivityRecognitionClient(),
Utility.DETECTION_INTERVAL_TIME, pendingIntent())
Here is my remove code
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(getActivityRecognitionClient(),
pendingIntent())
So my question is, is there a way to cancel all calls period to the activity recog. even if I dont know the pendingintent info?
So my question is, is there a way to cancel all calls period to the
activity recog.
If you refer the API of ActivityRecognitionApi it contains only two methods
https://developers.google.com/android/reference/com/google/android/gms/location/ActivityRecognitionApi
one for requesting updates
requestActivityUpdates(GoogleApiClient client, long detectionIntervalMillis, PendingIntent callbackIntent)
and
second one to remove updates
removeActivityUpdates(GoogleApiClient client, PendingIntent callbackIntent)
both methods need PendingIntent.
So obviously answer is NO.
Hope this will helps you.
Okay there seems to be no way to cancel the pending intents to the activity recog. LIke Nag stated however what I ended up doing was changing the name of my intentservice class and using it instead and keeping track of the pending Id info. Now I don't have any request coming in from previous calls
I am adding an event to my schedule
list and alarm has been fixed to that
event. I have to repeat alarm for
every one minute, from the before five
minutes of event ending time. In below
conditions I have to remove or cancel
alarm for particular event.
When I delete event from my schedule.
Event placed in schedules but I don't want alarm for event.
I am following concepts like sqlite database, Alarm manger, Services. I am confusing little bit using Services and pendingIntent. So, please suggest me the right way to approach my requirement.
You need to use the method cancel(...) from AlarmManager, using the same PendingIntent you used to set the alarm. Example:
this.getAlarmManager().cancel(mAlarmPendingIntent);
(this refers to the Activity or the Service from which you are cancelling the alarm).
Here is the link for the API.
Create the PendingIntent as:
mAlarmPendingIntent = PendingIntent.getActivity(this, requestCode, intent, flags);
The API doc for PendingIntent is here.