Update time for AlarmManager (Android) - android

I use AlarmManager to display a notification for an event at the event date and time.
But how can I update the time the AlarmManager sends the PendingIndent to my app, when an event is updated?
When an event is created the following code is called:
public void setOneTimeAlarm() {
Intent intent = new Intent(this, TimerReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_ONE_SHOT);
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, day-1);
c.set(Calendar.HOUR_OF_DAY, 18);
c.set(Calendar.MINUTE, 00);
long date = c.getTimeInMillis();
mAlarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent);
}
The indent called is TimerReciver:
#Override
public void onReceive(Context context, Intent intent) {
Log.v("TimerReceiver", "onReceive called!");
Intent notificationIntent = new Intent(context, ListTests.class);
PendingIntent contentIntent = PendingIntent.getActivity(context,
123, notificationIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Resources res = context.getResources();
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
long[] pattern = {0,300};
builder.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
.setTicker(res.getString(R.string.app_name))
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setVibrate(pattern)
.setContentTitle(res.getString(R.string.notification_title))
.setContentText(res.getString(R.string.notification_text));
Notification n = builder.build();
nm.notify(789, n);
}

I found the solution.. I turns out that the second argument to getBroadcast(Context context, int requestCode, Intent intent, int flags) makes the difference, even when the documentation says
requestCode Private request code for the sender (currently not used).
When a request id is used for each event, the alarm is updated and alarms are created for each event.
The reason is that with two different request codes, the filterEquals(Intent) will be false. Documentation of AlarmManager set(...) says:
If the time occurs in the past, the alarm will be triggered
immediately. If there is already an alarm for this Intent scheduled
(with the equality of two intents being defined by
filterEquals(Intent)), then it will be removed and replaced by this
one.
I also changed PendingIntent.FLAG_ONE_SHOT to PendingIndent.FLAG_CANCEL_CURRENT.

Related

Android AlarmManager only sending last scheduled notification

I am creating a research app that should prompt the user 4 times a day to enter their mood - by sending a notification, which when clicked launches the correct Activity. I am able to schedule these notifications using AlarmManager, however only the last scheduled notification ever shows. So although I schedule them for 9AM, 2PM, 5PM, and 8PM, it only ever sends a notification at 8PM.
How can I get all of the scheduled notifications to show?
Here is my code for setting (one of) the alarms (from a notification manager class). Note that al alarms are set using the same instance of AlarmManager:
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.HOUR_OF_DAY, 9);
cal.set(Calendar.MINUTE, 0);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), createPendingIntent(9, this));
Here is the createPendingIntent method (in the same notification manager class):
public static PendingIntent createPendingIntent(int hour, Context c){
Intent notificationIntent = new Intent(c, AlarmBroadcastReceiver.class);
notificationIntent.putExtra("time", hour);
PendingIntent pendingIntent = PendingIntent.getBroadcast(c, 0 , notificationIntent , PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
Here is the BroadcastReceiver for the alarm:
public class AlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationSender.createNotification(context);
}
}
And finally the createNotification method:
public static void createNotification(Context c){
Log.e("notif?", "creating");
Intent intent = new Intent(c, UpdateMoodActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
int notificationId = new Random().nextInt();
PendingIntent pendingIntent = PendingIntent.getActivity(c, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(c, "com.lizfltn.phdapp.notifChannelID")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("SoftMood")
.setContentText("Please record your mood")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(c);
notificationManager.notify(notificationId, builder.build());
}
Yes I know this isn't the best-practice way of doing things, or even the neatest, but unfortunately I need to get code working ahead of writing good code :P
I've tried various configurations of setting the alarm, e.g. using elapsed realtime instead of RTC, only setting the alarm, setting the exact alarm, etc, but there might be something fundamental I'm not understanding about how those work.
Any help appreciated!
Can you try with same id in pending intent and notify.?
Notification id in createNotification() method is random id.
int notificationId = new Random().nextInt();
and id used in createPendingIntent method is 0.
PendingIntent pendingIntent = PendingIntent.getBroadcast(c, 0 , notificationIntent , PendingIntent.FLAG_UPDATE_CURRENT);
Can you try with using same value for second parameter of getBroadcast?

Changing a variable from Notification Method

I added a notification feature to my app, when the user clicks on the notification it sends him to a certain activity in my app, but I also want it to change an integer variable number, I tried defining the variable static and do:
ActivityName.Variable = ActivityName.Variable + 1 or ActivityName.Variable++;
And it actually worked! but only when I change the date on my phone manually, so when the user sees the notification after waiting 1 day (the notification is daily) and clicks on it...he get to the activity but with no increase in the variable.
here's the notification codes:
public void setNotificationOn() { //This method sets the notification...so after 24h it will be triggered
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 24);
Intent intent = new Intent(getApplicationContext(), NotificationReceiverActivity.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
package com.example.wordspuzzlejsontest;
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
LevelActivity.stars++; //This is the variable which I'm trying to increase
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent repeating_intent = new Intent(context, LevelsListActivity.class);
repeating_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity
(context, 100, repeating_intent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setSmallIcon(android.R.drawable.star_big_off)
.setContentTitle("Collect your daily star")
.setContentText("Click to collect your daily star")
.setAutoCancel(true)
.setColor(Color.BLUE);
notificationManager.notify(100, builder.build());
}
}

How to update broadcast receiver. (multiple notification)

Variables in BroadcastReceiver are not updating every time i set a notification/alarm manager.
"receiver (recycler)" is from a fragment.
receiver" is from a BroadcastReceiver class.
onCreateView
intentAlarmManager = new Intent(context, NotificationReceiver.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, intentAlarmManager, PendingIntent.FLAG_UPDATE_CURRENT);
Notification Method
private void setNotification(int hour, int min, int interval, int uniqueID) {
//get instance of the calendar
calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, min);
//create delayed intent
pendingIntent = PendingIntent.getBroadcast(context, uniqueID, intentAlarmManager, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * (interval * 30), pendingIntent);
}
Recycler its attached to a switch listener
setNotification(Integer.parseInt(model.getHour()), Integer.parseInt(model.getMinute()), Integer.parseInt(model.getInterval()), Integer.parseInt(model.getTime()));
Receiver
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intentToStartWhenAlarmSets = new Intent(context, LoginActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), intentToStartWhenAlarmSets, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Content Title")
.setContentText("Notify " + HomeFragment.notifMedName)
.setSound(notifSound)
.setVibrate(pattern)
//swipable
.setAutoCancel(true);
Log.d(ContentValues.TAG, "receiver " + HomeFragment.notifMedName);
notificationManager.notify((int) System.currentTimeMillis(), builder.build());
I figured it out, i think. Although I'm not sure if this is the best/correct way (i'ts working though).
So in in my receiver class i added
intent.getStringExtra("string);
and in my fragment i added
intentAlarmManager.putExtra("string", notifMedName);
getActivity().sendBroadcast(intentAlarmManager);
and also i changed all pending intent from context to getActivity().
Feel free to answer if you guys have a better solution.
More info here.

Show status bar notification in certain time

I want to show the user notifications everyday in the same time. For now I only have this code:
My TimeAlarm.class that shows the notifications:
public class TimeAlarm extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
nm = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence from = "Nithin";
CharSequence message = "Crazy About Android...";
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(), 0);
Notification notif = new Notification(R.drawable.ic_launcher,
"Crazy About Android...", System.currentTimeMillis());
notif.setLatestEventInfo(context, from, message, contentIntent);
notif.sound = Uri.parse("android.resource://"
+ context.getPackageName() + "/" + R.raw.test);
// r.play();
nm.notify(1, notif);
}
}
And initialization of the notifications to show every 5 seconds:
public void setRepeatingAlarm() {
Intent intent = new Intent(this, TimeAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
(5 * 1000), pendingIntent);
}
Now my question is how should I modify this code to set the notification to repeat every day in certain time. Example every day in 14:36 o'clock?
The easy-but-inexact way is to change System.currentTimeMillis() to a calculation of 14:36 tomorrow, probably using a Calendar object:
Calendar cal=Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 14);
cal.set(Calendar.MINUTE, 36);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
if (cal.getTimeInMillis() < System.currentTimeMillis()) {
cal.add(Calendar.DAY_OF_YEAR, 1);
}
I say "easy-but-inexact" because Android 4.4 has changed the behavior of setRepeating() to be inexact, once your android:targetSdkVersion is 19 or higher. If you need exact alarms, you will need to use setExact() and do your own "repeating" (by calling setExact() again when the alarm goes off). You would still use the same Calendar sort of calculation, just on every setExact() call.

how to schedule a notification using alarm manager

I have defined a receiver which should fire the notification when it is called. This works only if I call the receiver straight away.
I am unable to schedule it for a specific date.
Calendar c = Calendar.getInstance();
c.set(2014, 4, 18, 2, 20, 0);
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(getBaseContext().ALARM_SERVICE);
int id = (int) System.currentTimeMillis();
Intent intent = new Intent(this, TimeAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
This is my Receiver class:
public class TimeAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent paramIntent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent("android.intent.action.VIEW");
intent.setData(Uri.parse("http://www.sdfasdf.ch"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Create the notification
Notification notification = new Notification(R.drawable.android_anydont_logo, "sdfs", System.currentTimeMillis());
notification.setLatestEventInfo(context, "something something", "darkside",pendingIntent);
// Fire the notification
notificationManager.notify(1, notification);
}
}
This is the definition in the manifest:
receiver
android:name="com.hack.doneit.utils.TimeAlarm"
android:process=":remote" />
My problem is that i am unable to set the alarm to trigger the receiver at a specific time in the future. A specific day would be enough.
Problem is with the Month value you have set. I believe you thought for month April the value is 4. The value of month starts from 0 , so April will be 3.
Change you code on month as Calendar.APRIL or set value as 3
c.set(2014, Calendar.APRIL, 17, 20, 43, 0);
This should work. Apart from this your codes are perfect.
Note: Your using the Notification deprecated API's . Use Notification Builder

Categories

Resources