I need to show a notification at 3 AM everyday. It is working fine and sending notification around 3 AM. But when I test in my phone the notification comes immediately. I read that if the time is already crossed it will show the notification. I am fine with this.
Issue: When i click the notification it opens my activity correctly. But after few seconds it is loading another notification. If i click that again it is closing the notification and creating a new one after few seconds.
Here is the code:
1. In the activity onCreate()
Calendar calendar = Calendar.getInstance();
// calendar.set(Calendar.MONTH, 10);
// calendar.set(Calendar.YEAR, 2014);
// calendar.set(Calendar.DAY_OF_MONTH, 13);
calendar.set(Calendar.HOUR_OF_DAY, 3);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
Intent myIntent = new Intent(LitCalActivity.this, MyReceiver.class);
pendingIntent = PendingIntent.getBroadcast(LitCalActivity.this, 0, myIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
In My service Class
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// Code to notification setup
Intent litrcalintent = new Intent(this, LitCalActivity.class);
Bundle bundle = new Bundle();
bundle.putString("FromNotify", "YES");
litrcalintent.putExtras(bundle);
PendingIntent pIntent = PendingIntent.getActivity(this, 0,
litrcalintent, PendingIntent.FLAG_UPDATE_CURRENT);
SimpleDateFormat format = new SimpleDateFormat("MMMM dd yyyy");
String today = format.format(currentDate);
String todayDetails = getLitCalDetails();
Notification notification = new Notification.Builder(this)
.setContentTitle("Liturgical Calendar for " + today)
.setContentText(todayDetails)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true)
.setOngoing(false)
.addAction(R.drawable.ic_launcher, "more...", pIntent).build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}
Related
I have a problem with notifications in my app. I want to set multiple notifications for different hours of the day. For example, let's take 8, 12 and 23 o'clock. But only the one at 23 o'clock triggers every day. What's wrong with my code and will it work even if the app is killed?
Here's the code that sets alarms in my activity
public void myAlarm(int hour, int minute) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
Intent intent = new Intent(getApplicationContext(), Reminder.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
and this is what I wrote in onCreate
myAlarm(8, 0);
myAlarm(12, 0);
myAlarm(23, 0);
this is my receiver
public class Reminder extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent in = new Intent(context, MySecoundActivity.class);
in.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, in, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "Reminder")
.setSmallIcon(R.drawable.bell)
.setContentTitle("Notification!")
.setContentText("Text of notification")
.setColor(0xfb3ff)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH);
NotificationManagerCompat notificationMngr = NotificationManagerCompat.from(context);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Reminder";
String description = "reminder channel";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel("Reminder", name, importance);
channel.setDescription(description);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
notificationMngr.notify(200, builder.build());
}
Receiver is in android manifest
<receiver android:name=".Reminder"/>
This is the expected behavior since in your code, when you set the alarm, you have to give every PendingIntent unique requestCode which in your case remains the same, i.e., 0. So when you set another alarm with same requestCode, the last alarm gets updated to the new time instead of creating a new alarm. So only your last alarm works. So at the time of setting the alarm, in your PendingIntent.getBroadcast(), instead of the 0, you could use either the Random class to generate a random number every time or you could just use (int)System.currentTimeMillis() which would always be a different number.
I am able to get notifications at a particular time in future by using Calendar class java (Example 9:15am). The Alarm manager sends the broadcast to the broadcast receiver whenever the time is 9:15am but when I open the app after 9:15am (Example 9:20am). I receive the same notification. Can anyone help my about this.
My Manifest
<receiver android:name=".others.NotificationReceiver"/>
Notification Receiver.java
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
createNotification(context);
}
private void createNotification(Context context) {
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel linkChannel = new NotificationChannel(link_channel_id, "Link Channel", NotificationManager.IMPORTANCE_HIGH);
linkChannel.setDescription("This channel is used to show Zoom Links");
notificationManager.createNotificationChannel(linkChannel);
}
Notification notification = new NotificationCompat.Builder(context, link_channel_id)
.setSmallIcon(R.mipmap.ic_launcher_foreground)
.setContentTitle("Test Notification")
.setContentText("This is a test notification")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.build();
notificationManager.notify(1, notification);
}
}
My Alarm Manager
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 10);
calendar.set(Calendar.SECOND, 0);
Intent myIntent1 = new Intent(this, NotificationReceiver.class);
myIntent1.setAction(ACTION_ONE);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(this, 1, myIntent1, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent1);
I start to combine alarm manager and notification manager on android, and this is my code:
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setReminderAlarm();
}
public void setReminderAlarm() {
Intent intent = new Intent(MainActivity.this, ReminderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ReminderReceiver.NOTIF_ID, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 59);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 86400000L, pendingIntent);
}
ReminderReceiver.java
public static int NOTIF_ID = 101;
#Override
public void onReceive(Context context, Intent intent) {
showAlarmNotification(context);
}
public void showAlarmNotification(Context context) {
Intent intentClick = new Intent(context, MainActivity.class);
PendingIntent pendingClick = PendingIntent.getActivity(context, 0, intentClick, 0);
NotificationManager notificationManagerCompat = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.cinema)
.setContentTitle(title)
.setContentIntent(pendingClick)
.setContentText(message)
.setColor(ContextCompat.getColor(context, android.R.color.transparent))
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
.setSound(alarmSound)
.setAutoCancel(true);
notificationManagerCompat.notify(NOTIF_ID, builder.build());
}
Every time I run the application, the notification always appears even though I have set the time. How do I prevent that?
Thank you.
The issue is you are setting the time to current day. So if you are opening your app after 6:00, your alarm manager will immediately fire.
You need to check whether the time is over 6:00 for the current day, if yes you need to change the date to the next day:
public void setReminderAlarm() {
Intent intent = new Intent(MainActivity.this, ReminderReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ReminderReceiver.NOTIF_ID, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int curHr = calendar.get(Calendar.HOUR_OF_DAY);
// Checking whether current hour is over 6
if (curHr >= 6)
{
// Since current hour is over 6, setting the date to the next day
calendar.add(Calendar.DATE, 1);
}
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 59);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 86400000L, pendingIntent);
}
I'm looking to create a function for an Android app in which I get a notification every 25th day of the month indicating I have to do a certain task.
I've been able to display the notification using the following code :
public class NotificationPublisher extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
long[] pattern = {0, 300, 0};
PendingIntent pi = PendingIntent.getActivity(context, 01234, intent, 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.small_logo_ico)
.setContentTitle(context.getResources().getString(R.string.notification_title))
.setContentText(context.getResources().getString(R.string.notification_content))
.setVibrate(pattern)
.setAutoCancel(true);
mBuilder.setContentIntent(pi);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(01234, mBuilder.build());
}
}
Now this system only works when I have my app open and doesn't allow me to display this when the app is closed. I've searched around and came to this:
Android notification at specific date
After trying this out (the schedule part) I noticed that it doesn't work when I close the app, as I get an error about unregistering the Receiver, doing this (unregistering) results in the receiver being canceled, and the notification can not be showed.
code used for the schedule:
NotificationPublisher receiver = new NotificationPublisher();
this.receiver = receiver;
IntentFilter filter = new IntentFilter("ALARM_ACTION");
registerReceiver(receiver, filter);
Intent intent = new Intent("ALARM_ACTION");
intent.putExtra("param", "My scheduled action");
PendingIntent operation = PendingIntent.getBroadcast(this, 0, intent, 0);
// I choose 15s after the launch of my application
alarms.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+15000, operation) ;
Is there anything I'm missing, or am I using the wrong methods to schedule a notification on a certain date? ( The current notification is set to be scheduled 15 seconds in the future, this is just for testing, I've got a function ready to display this at a certain date)
This is used to notify on middle of the month. Maybe You can get from below code.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH, 15);
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
if (calendar.getTimeInMillis() < System.currentTimeMillis()) {
calendar.add(Calendar.DAY_OF_YEAR, 30);
}
Intent myIntent = new Intent(getApplicationContext(), MyReceiver.class);
myIntent.putExtra("NOTI_MSG",getString(R.string.notification_sidas));
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), NOTI_REQ_CODE_SIDAS, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY * 30, pendingIntent);
}
I'm using the AlarmManager to fire a notification daily in specific time which is selected via time picker. The notification fired correctly in the same day but doesn't repeat correctly every day!!!
This is the method for setting the notification using setRepeating():
public void witer_reminder(View view)
{
am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, Witer_Notification.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
Calendar calSet = (Calendar) cal.clone();
calSet.set(Calendar.HOUR_OF_DAY, picker.getCurrentHour());
calSet.set(Calendar.MINUTE, picker.getCurrentMinute());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
if(calSet.compareTo(cal) <= 0)
{
// Today Set time passed, count to tomorrow
calSet.add(Calendar.DATE, 1);
}
am.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
24 * 60 * 60 * 1000, pendingIntent);
}
and this is the BroadcastReciver class:
public class Witer_Notification extends BroadcastReceiver
{
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent)
{
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
PendingIntent actiontIntent = PendingIntent.getActivity(context, 0,
new Intent(context, Suggestion.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("")
.setStyle(new NotificationCompat.BigTextStyle().bigText(""));
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
// mBuilder.setStyle(new NotificationCompat.InboxStyle());
NotificationManager mNotificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
BTW, the application target is SDK 19.
I found that the setExact() replacing to set()
Correct.
it's not applicable for intervalAtMilis as a parameter
Not directly. But, when you get control in your BroadcastReceiver from the setExact() event, call setExact() again to schedule the next event.
I didn't find anything for setRepeating()
There is no simple solution, because Google is trying to point out to you that this is bad for the battery. Using setExact() as described above is your only option for exact repeating.