User can set their own repeat interval, for example he/she selected 5 minutes to be reminded of the new goal she set. The reminder will start on the goal's start date which is also set by the user.
No problem with setting goal, and setting the repeat interval. The problem is it wont work.
What i would like to happen: This is an example
Goal 1 starts tomorrow. User will get reminder of Goal 1 in every 1 hour tomorrow.
Here's my code:
public void setReminder(){
List<Goals> oneGoal = dbhandler.getLatestGoal(goal_id);
for (final Goals goals : oneGoal) {
if (repeat.isChecked()) {
long futureInMillis = 0;
dbhandler.updateReminders("true",choiceNumber,choiceRepeat,goal_id);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.DATE,Integer.parseInt(goals.getSDay())); //1-31
cal.set(Calendar.MONTH,Integer.parseInt(goals.getSMonth())-1); //first month is 0!!! January is zero!!!
cal.set(Calendar.YEAR, Integer.parseInt(goals.getSYear()));//year...
//assigned a unique id to notifications
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
//Create a new PendingIntent and add it to the AlarmManager
Intent intent3 = new Intent(this, TimeAlarm.class);
intent3.putExtra("goalid", Integer.toString(goal_id));
PendingIntent pendingIntent = PendingIntent.getActivity(this,
goals.getGoalId(), intent3, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
(AlarmManager) getSystemService(Activity.ALARM_SERVICE);
if (choiceRepeat.equalsIgnoreCase("Seconds")) {
am.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(), 1000 * choiceNumber,
pendingIntent);
} else if (choiceRepeat.equalsIgnoreCase("Minutes")) {
am.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(), 1000 * 60 * choiceNumber,
pendingIntent);
} else if (choiceRepeat.equalsIgnoreCase("Hours")) {
am.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(), 1000 * 60 * 60 * choiceNumber,
pendingIntent);
}
MessageTo.message(SetReminderActivity.this, "You will be reminded every "+choiceNumber+" "+choiceRepeat+" for the new goal.");
//am.cancel(pendingIntent);
}else{
MessageTo.message(SetReminderActivity.this, "You've chosen not to set reminder for the new goal.");
}
}
}
TimeAlarm.java // for the notifications
public class TimeAlarm extends BroadcastReceiver {
NotificationManager nm;
MyDBAdapter dbhandler;
#Override
public void onReceive(Context context, Intent intent) {
int goal_id = Integer.parseInt(intent.getStringExtra("goalid"));
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(), 0);
//assigned a unique id to notifications
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
List<Goals> oneGoal = dbhandler.getLatestGoal(goal_id);
for (final Goals goals : oneGoal) {
Notification mNotification = new Notification.Builder(context)
.setContentTitle("A Reminder from GSO")
.setContentText(goals.getGoalName())
.setSubText(goals.getStartDate() + " - " + goals.getEndDate())
.setSmallIcon(R.drawable.gsoicon)
.setContentIntent(contentIntent)
.setSound(soundUri)
.build();
nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
// If you want to hide the notification after it was selected, do the code below
mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(m, mNotification);
}
}
}
in Android Manifest:
<receiver android:name=".TimeAlarm" />
I can't tell what wrong with my code. Pls. help.
You are only setting the alarm using AlarmManager's set() method. You should use setRepeating() method for repeating the alarm events.
So, your below line
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
should be replaced with
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
You can also refer this Example : Create Repeating Alarm .
Example to repeat event on every two minutes
AlarmManager am = (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(),2*60*60,pendingIntent);
You have to declare the receiver in your AndroidManifest.xml
<receiver android:name="TimeAlarm" >
See: http://developer.android.com/guide/topics/manifest/receiver-element.html
Related
I am working on an application in which i want to make a notification on Friday every week i have tried this code but it make notification on every day
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK,6);
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
String h = String.valueOf(hourOfDay);
String m = String.valueOf(minute);
Intent intent = new Intent(getApplicationContext(), notification.class);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 7*AlarmManager.INTERVAL_DAY, pendingIntent);
Toast.makeText(Settings.this, h+ " : " + m , Toast.LENGTH_SHORT).show();
Notification.class
public class notification extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PendingIntent pendingIntent=PendingIntent.getActivity(context,0,new Intent(context,The_main.class),0);
NotificationCompat.Builder builder=new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.awq)
.setContentTitle("remainder")
.setContentText(" time to read");
builder.setContentIntent(pendingIntent);
builder.setDefaults(NotificationCompat.DEFAULT_SOUND);
builder.setAutoCancel(true);
NotificationManager notificationManager=(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(1);
notificationManager.notify(1,builder.build());
}}
Try replacing
`7*AlarmManager.INTERVAL_DAY`
with
7 * 24 * 60 * 60 * 1000 (7days Interval in milliseconds)
I'm trying to cancel the repeating notifications on a particular date, so I'm setting it in a broadcast receiver which is fired on that particular time cancelling the repeating notifications through that unique id. but it is not cancelling the notifications. I have tried two techniques both are mentioned below.
mainActivity's code where I'm setting the Alarm.
Log.v("setting range alarm","key range id = " + keyIds[j] + "time = " + RangeTimes[j]);
// Setting the alarm for repeating notifications, with different broadcast Receiver (alertIntent).
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, RangeTimes[j], AlarmManager.INTERVAL_DAY,
PendingIntent.getBroadcast(this, keyIds[j], alertIntent, PendingIntent.FLAG_UPDATE_CURRENT)); // for exact repeating THIS
Log.v("setting range alarm","key range id = " + keyIds[j] + "Cancel time = " + CancelRangeTimes[j]);
// Setting the alarm for cancellin the repeating notifications, with different broadcast Receiver(cancelIntent).
cancelIntent.putExtra("CancelID", keyIds[j]);
cancelIntent.putExtra("key", pendingIntent);
AlarmManager alarmManager1 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager1.set(AlarmManager.RTC_WAKEUP, CancelRangeTimes[j],
PendingIntent.getBroadcast(this, keyIds[j], cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT)); // for exact repeating THIS
here is the cancelling broadcast reciver which is not working even though it is getting called on the right time.
#Override
public void onReceive(Context context, Intent intent) {
String pleaseText = intent.getStringExtra("text");
// Methid # 1 ( By getting the Alarm id through intent and trying to cancel on the same id
/*
int cancelReqCode = intent.getIntExtra("CancelID", 0);
Log.v("setting the cancel", "inside broadCast reciver " + cancelReqCode);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, cancelReqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Log.v("setting the cancel", "inside broadCast reciver " + pendingIntent);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pendingIntent);
*/
// Methid # 2
Log.i("okk", "please text insode cancel" + pleaseText);
PendingIntent pendingIntent = intent.getParcelableExtra("key");
Log.v("setting the cancel","inside broadCast reciver " + pendingIntent );
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pendingIntent);
}
// below is the mainActvity's code where i'm setting alaram managers, alertIntent, CancelIntent and Pending Intents. I have omitted the code where it is getting the array values and setting them because it was useless here, but every date value is correct. this setAlarm() is getting called in the onCreate method.
public class MainActivity extends ActionBarActivity implements AsyncResponse, View.OnClickListener {
AlarmManager alarmManager;
PendingIntent pendingIntent;
public void setAlarm1() {
long[] RangeTimes = new long[C.getCount()];
long[] CancelRangeTimes = new long[C.getCount()];
String rangeCheck = "false" ;
int[] KeyRangeIds = new int[C.getCount()];
Intent alertIntent = new Intent(this, AlertReceiver.class);
Intent cancelIntent = new Intent(this, CancelAlarmBroadcastReceiver.class);
alertIntent.putExtra("strings", DealTimes);
cancelIntent.putExtra("strings", DealTimes);
// ------------------------- SETTING ALARM --------------------------------
for (int i = 0; i < UserFoodType.length; i++) {
for (int j = 0; j < C.getCount(); j++) {
RangeTimes[j] = calendar.getTimeInMillis();
CancelRangeTimes[j] = calendar1.getTimeInMillis();
}
if(FoodType[j].equals(UserFoodType[i]))
{
for (int k = 0; k < UserDealZone.length; k++) {
if(DealZone[j].equals(UserDealZone[k]))
{
Log.v("setting range alarm","key range id = " + keyIds[j] + "time = " + RangeTimes[j]);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, RangeTimes[j], AlarmManager.INTERVAL_DAY,
PendingIntent.getBroadcast(this, keyIds[j], alertIntent, PendingIntent.FLAG_UPDATE_CURRENT)); // for exact repeating THIS
Log.v("setting range alarm","key range id = " + keyIds[j] + "Cancel time = " + CancelRangeTimes[j]);
// alertIntent.putExtra("cancelID", keyIds[j]);
cancelIntent.putExtra("CancelID", keyIds[j]);
cancelIntent.putExtra("key", pendingIntent);
AlarmManager alarmManager1 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager1.set(AlarmManager.RTC_WAKEUP, CancelRangeTimes[j],
PendingIntent.getBroadcast(this, keyIds[j], cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT)); // for exact repeating THIS
}
}
}
You are putting an extra in cancelIntent, like this:
cancelIntent.putExtra("key", pendingIntent);
however, pendingIntent is never initialized, so it will be null.
When CancelAlarmBroadcastReceiver.onReceive() is called, this code:
PendingIntent pendingIntent = intent.getParcelableExtra("key");
is probably returning null. You are logging that, you should be able to check.
In any case, if pendingIntent is null, calling AlarmManager.cancel() won't do anything.
I am currently debugging an issue with notifications inside my application. For some context, what I'd like to do is schedule notifications that should popup whenever a rocket launch is occurring. What I was doing was, after getting a list of scheduled launches from an API, I would take the launch date (in milliseconds since Jan 1 1970) and subtract the System.currentTimeMillis() from it. I would then use the resulting time to schedule the notification in the future, represented as System.currentTimeMillis() + timeDifference. I noticed that for whatever reason, only 1 notification is ever displayed.
I've tried debugging by scheduling notifications at 2, 4, and 6 minutes in the future, however a notification is only displayed at the 6 minute mark.
Some relevant code is below:
public void scheduleNotifications(List<Launch> launches) {
for(int i = 0; i < launches.size(); i++) {
SimpleDateFormat format = new SimpleDateFormat("MMMM dd, yyyy HH:mm:ss z");
Date date = null;
try {
date = format.parse(launches.get(i).getWindowstart());
} catch (ParseException e) {
e.printStackTrace();
}
long timeBetween = date.getTime() - System.currentTimeMillis();
Integer id = Long.valueOf(date.getTime()).intValue();
Intent notificationIntent = new Intent(this, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, id);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, getNotification(launches.get(i).getRocket().getName(), launches.get(i).getLocation().getPads().get(0).getName()));
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//Debug. Schedule at 2, 4, 6 minutes.
if (i == 0) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 120000, pendingIntent);
}
if (i == 1) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 240000, pendingIntent);
}
if (i == 2) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 360000, pendingIntent);
}
}
}
private Notification getNotification(String rocketName, String padName) {
Notification.Builder builder = new Notification.Builder(this);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
builder.setContentIntent(pendingIntent);
builder.setContentTitle("Upcoming Launch");
builder.setContentText("A launch of a " + rocketName + " is about to occur at " + padName + ". Click for more info.");
builder.setSmallIcon(R.drawable.rocket_icon);
return builder.build();
}
Broadcast Receiver:
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}
I'd like to know why only a single notification is ever presented, as well as what I need to add to achieve the previously stated goal.
When you set an alarm using AlarmManager, it automatically cancels any existing alarm that has a matching PendingIntent. Since all your PendingIntents contain the same components, every time you set an alarm, the previously set ones are automatically cancelled.
If you want to set multiple alarms, you must make sure that each of the PendingIntents is unique. You can do this in one of the following ways:
Use a different requestCode (second parameter to PendingIntent.getBroadcast()) for each PendingIntent
Use a different ACTION in the Intent you pass to PendingIntent.getBroadcast() for each PendingIntent
I am trying to set a repeating alarm that will will download a file every minute but only between 8:00 and 22:00. I feel like I'm really close but I can't see the error I'm making. Currently the broadcast receiver is not activating. If set the repeating alarm manually to alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10000, 60000,pendingIntent); it works fine. Any guidance would be much appreciated.
protected void scheduleNextUpdate()
{
Intent intent = new Intent("TEST");
PendingIntent pendingIntent =
PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
int updateInterval = 1;
long nextUpdate =(60000 * updateInterval);
long currentTimeMillis = System.currentTimeMillis();
long nextUpdateTimeMillis = currentTimeMillis + nextUpdate;
Time nextUpdateTime = new Time();
nextUpdateTime.set(nextUpdateTimeMillis);
if (nextUpdateTime.hour < 8 || nextUpdateTime.hour > 22)
{
nextUpdateTime.hour = 8;
nextUpdateTime.minute = 0;
nextUpdateTime.second = 0;
nextUpdateTimeMillis = nextUpdateTime.toMillis(false) + DateUtils.DAY_IN_MILLIS;
}
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10000, nextUpdateTimeMillis,pendingIntent);
boolean alarmUp = (PendingIntent.getBroadcast(this, 0,
new Intent("TEST"),
PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp)
{
Log.d("myTag", "Alarm is already active");
}
}
You should set your alarm reapeating when it is between 8:00 and 22:00 like you mentioned:
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10000, 60000,pendingIntent);
This will repeat every minute. But you must explicitly cancel the alarm. You can cancel it after download is completed, by checking if its already 22:00. Or by another alarm that will be triggered when it is 22:00. Otherwise it will not stop.
use alarmManager.cancel (pendingIntent)
described here: http://developer.android.com/reference/android/app/AlarmManager.html#cancel(android.app.PendingIntent
Hope this helps.
I'd like to have a notification done weekly from the day it was set. It initializes when it gets called but not the second time.(I fast forwarded the phone clock to see if it would call it but it didn't). It must be the 7*calendar.getTimeInMillis(). How else would I go about having it set for weekly?
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, mHour);
calendar.set(Calendar.MINUTE, mMinute);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, OnBootReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
//am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 7*calendar.getTimeInMillis(), pendingIntent);
BroadCastReceiver class:
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence from = "from";
CharSequence message = "message";
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
Notification notif = new Notification(icon, tickerText, when);
notif.setLatestEventInfo(context, from, message, contentIntent);
nm.notify(1, notif);
The 7*calendar.getTimeInMillis() is indeed the problem as calendar.getTimeInMillis() returns the time since 1970, so you basically set the repeating to ~42.5 * 7 years from now. You need to set the offset, e.g. 7 (days) * 24 (hours) * 60 (minutes) * 60 (seconds) * 1000 (millies).
After we cleared that - I suggest you avoid using the repeating, and instead set a new alarm each time the invoked code finishes its work, as there are some possible problems with the repeating mechanism.
You don't want the current date * 7 you want:
7 days = 604 800 000 milliseconds
This is how many milliseconds are in 7 days
i.e.
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 604800000L, pendingIntent);