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.
Related
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);
in my program i set notifications with a string and its clock to get a notification with that string at its clock.(I mean user wants to get a notification with a string at demanding time, and user gave me a lot of strings and their clocks.) And if the user want to cancel that notification i don't know how to do it.
I tried alarmManager.cancel(pendingIntent) but I want to cancel the only one notification not all of them. Also, it doesn't cancel any notification too.
here is the code in the main
public void gecikmeliGoster(String plan, int yil, int ay, int gun, String saat){
NotificationCompat.Builder builder;
NotificationManager bildirimYoneticisi = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent ıntent = new Intent(HatirlaticiKur.this, AlarmReciever.class);
PendingIntent gidilecekIntent = PendingIntent.getActivity(this, 1, ıntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String kanalId = "kanalId";
String kanalAd = "kanalAd";
String kanalTanım = "kanalTanım";
int kanalOnceligi = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel kanal = bildirimYoneticisi.getNotificationChannel(kanalId);
if (kanal == null) {
kanal = new NotificationChannel(kanalId, kanalAd, kanalOnceligi);
kanal.setDescription(kanalTanım);
bildirimYoneticisi.createNotificationChannel(kanal);
}
builder = new NotificationCompat.Builder(this, kanalId);
builder.setContentTitle("Hatırlatıcı")
.setContentText(plan)
.setSmallIcon(R.drawable.hatirlatici)
.setAutoCancel(true)
.setContentIntent(gidilecekIntent);
} else {
builder = new NotificationCompat.Builder(this);
builder.setContentTitle("Hatırlatıcı")
.setContentText(plan)
.setSmallIcon(R.drawable.hatirlatici)
.setContentIntent(gidilecekIntent)
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH);
}
Intent broadcastIntent = new Intent(HatirlaticiKur.this, AlarmReciever.class);
broadcastIntent.putExtra("nesne", builder.build());
PendingIntent gidilecekBroadcast = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//long gecikme = SystemClock.elapsedRealtime() + 5000; //bu 5 saniyede bir bildirim gelmesi için falan
String[] noktasiz = saat.split(":");
int akrep = Integer.parseInt(noktasiz[0]);
int yelkovan = Integer.parseInt(noktasiz[1]);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.YEAR, yil);
calendar.set(Calendar.MONTH, ay);
calendar.set(Calendar.DATE, gun);
calendar.set(Calendar.HOUR_OF_DAY, akrep);
calendar.set(Calendar.MINUTE, yelkovan);
calendar.set(Calendar.SECOND, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 0, gidilecekBroadcast);
}
and here is the code in AlarmReceiver
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager bildirimYoneticisi = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification bildirim = intent.getParcelableExtra("nesne");
bildirimYoneticisi.notify(1,bildirim);
}
}
I want to cancel demanding notifications, i will appreciate your help
use used 0 id for setting alarm
PendingIntent gidilecekBroadcast = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
You need uniqueid for all notification set using alarmmanager
then based on uniqueid you can cancel alarm
PendingIntent gidilecekBroadcast =
PendingIntent.getBroadcast(getApplicationContext(), uniqueid , broadcastIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.cancel(gidilecekBroadcast);
I want the code to execute a notification once every day at 07 am. I created a debug apk and installed it to see how it performs and noticed, that it actually sends a notification at about 07 am, but if you click on the notification and get into the app and close it afterwars, it sends a notification again. Does someone see a mistake in the code?
this is the code in the MainActivity.java (the notification part):
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent_anmeldeActivity = new Intent(this, anmeldeActivity.class);
intent_WebViewActivity = new Intent(this, WebViewActivity.class);
prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
prefsEditor = prefs.edit();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 07);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
intent_notification = new Intent(this, NotificationClass.class);
Intent intent1 = new Intent(MainActivity.this, NotificationClass.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Also it sends notifications kind of randomly.
Thanks in advance!
EDIT:
public class NotificationClass extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
loadText loadText = new loadText();
loadText.startAsyncTask(context);
} }
In AsyncTask class loadText, the class NotificationBuilding is executed in onPostExecute:
public class NotificationBuilding {
Context mContext = null;
int ID = 1;
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
long when = System.currentTimeMillis();
public void startNotificationBuilding(Context con, String title, String text) {
this.mContext = con;
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(mContext, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mNotifyBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(
mContext)
.setSmallIcon(R.drawable.ic_stat_name)
.setColor(Color.argb(255, 234, 146, 21))
.setContentTitle(title)
.setContentText(text)
.setSound(alarmSound)
.setAutoCancel(true)
.setWhen(when)
.setContentIntent(pendingIntent)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
.setLights(Color.argb(255, 234, 146, 21), 1000, 10000)
.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
notificationManager.notify(ID, mNotifyBuilder.build());
ID++;
} }
// Set the alarm to start at approximately 7:00 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 07);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.**setInexactRepeating**(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
Decide how precise your alarm needs to be
As described above, choosing the alarm type is often the first step in creating an alarm. A further distinction is how precise you need your alarm to be. For most apps, setInexactRepeating() is the right choice. When you use this method, Android synchronizes multiple inexact repeating alarms and fires them at the same time. This reduces the drain on the battery.
For the rare app that has rigid time requirements—for example, the alarm needs to fire precisely at 8:30 a.m., and every hour on the hour thereafter—use setRepeating(). But you should avoid using exact alarms if possible.
With setInexactRepeating(), you can't specify a custom interval the way you can with setRepeating(). You have to use one of the interval constants, such as INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY, and so on. See AlarmManager for the complete list.
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.