android alarmManager setRepating time delay problem - java

I want to send a notification with the alarm manager in my application. I am using the setRepeating method because it should be in intervals. but notifications always come delayed.
For example, I would like to receive a notification at 12:14. but notification is coming sometimes 12:17, sometimes 12:20
Thanks in advance
Note: doze mode off
For Example:
thatDay Sat Apr 25 16:30:00 GMT+03:00 2020
today Sat Apr 25 16:07:44 GMT+03:00 2020
thatDay.getTimeInMillis() = 1587821400000
#Override
protected void onStop() {
if (notification) {
Calendar thatDay = Calendar.getInstance();
Calendar today = Calendar.getInstance();
int today_month_day = today.get(Calendar.DAY_OF_MONTH);
int today_month = today.get(Calendar.MONTH);
int today_year = today.get(Calendar.YEAR);
thatDay.setTime(new Date(0));
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day);
thatDay.set(Calendar.MONTH, today_month);
thatDay.set(Calendar.YEAR, today_year);
thatDay.set(Calendar.HOUR_OF_DAY, 8);
thatDay.set(Calendar.MINUTE, 0);
thatDay.set(Calendar.SECOND, 0);
thatDay.set(Calendar.MILLISECOND, 0);
Calendar calendar = Calendar.getInstance();
if (calendar.get(Calendar.HOUR_OF_DAY) < 23 && calendar.get(Calendar.HOUR_OF_DAY) > 7) {
if (calendar.get(Calendar.MINUTE) < 30) {
thatDay.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
thatDay.set(Calendar.MINUTE, 30);
} else {
thatDay.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
}
} else if (thatDay.getTimeInMillis() - today.getTimeInMillis() < 0) {
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day + 1);
} else {
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day);
}
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("NotificationID", 6);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 7, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Objects.requireNonNull(alarmManager).setRepeating(AlarmManager.RTC_WAKEUP, thatDay.getTimeInMillis(), waterList[waterCheck], pendingIntent);
super.onStop();
}
#SuppressLint("BatteryLife")
#RequiresApi(api = Build.VERSION_CODES.M)
private void requestBattery() {
Intent intent = new Intent();
String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (!(Objects.requireNonNull(pm).isIgnoringBatteryOptimizations(packageName))) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivityForResult(intent, BATTERY_PERMISSION);
}
}

This is because setRepeating is only fired, when something else is happening in the background. Mainly this is due to battery saving. The best way to set a repeating alarm is to use setExact and set another alarm once the first one was fired.
Alarmmanager:
public class AlarmManagerSetup {
public static Boolean alarmActivated;
public static Long milliSeconds;
public void startAlarm(Calendar c, Context context, Database database) {
android.app.AlarmManager alarmManager = (android.app.AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, 0);
c.setTimeInMillis(milliSeconds);
//compares to the current time and only adds when it is later than now
if (c.before(Calendar.getInstance())) {
c.add(Calendar.DATE, 1);
}
if (Build.VERSION.SDK_INT >= 23) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
}
And inside the Alert Receiver you do this:
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Context appContext = context.getApplicationContext();
CalendarSearch calendar = new CalendarSearch(context);
calendar.calendar();
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification(appContext);
notificationHelper.getManager().notify(1, nb.build());
AlarmManagerSetup alarmManager = new AlarmManagerSetup();
Calendar c = Calendar.getInstance();
c.setTimeInMillis(milliSeconds);
c.add(Calendar.DATE, 1);
milliSeconds = c.getTimeInMillis();
alarmManager.startAlarm(c, appContext, database);
}

Related

Send multiple messages in different times Android Java

So, I wanna build a scheduled message. But when I try to send more than one message, the other messages can't be delivered. I wonder how to do that.
onTimeSet method
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
DateFormat formatter = new SimpleDateFormat("EEE, d MMM yyyy HH:mm");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE)+1);
Log.d("Current time: ", formatter.format(calendar.getTime()));
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, 0);
if (c.getTimeInMillis() <= calendar.getTimeInMillis()){
Log.d("Tag: ", "Denied");
Toast.makeText(this, "You can't send it if it's too early!", Toast.LENGTH_SHORT).show();
} else {
Log.d("Tag: ", "Approved");
Toast.makeText(this, "Success!", Toast.LENGTH_SHORT).show();
startSchedule(c);
Intent intent = new Intent(MessageActivity.this, MessageActivity.class);
startActivity(intent);
finish();
}
}
startSchedule method
private void startSchedule(Calendar calendar) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlertReceiver.class);
intent.putExtra("number", number);
intent.putExtra("body", body);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
DateFormat formatter = new SimpleDateFormat("EEE, d MMM yyyy HH:mm");
Log.d("Test: ", ""+calendar.getTimeInMillis());
Log.d("Date: ", ""+formatter.format(calendar.getTimeInMillis()));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
}
AlertReceiver class
public class AlertReceiver extends BroadcastReceiver {
String number, body;
#Override
public void onReceive(Context context, Intent intent) {
Log.d("Test: ", "Worked");;
Bundle bd = intent.getExtras();
if(bd == null){
number = "";
body = "";
}else {
number = bd.getString("number");
body = bd.getString("body");
}
Log.d("Number: ", number +"\nBody: "+body);
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(number, null, body, null, null);
}
}
Please let me know if you guys know what I should do to make things right, thanks a lot!

Setting Alarm for Particular Timings with Respect to Start Date and End Date of an Event in Android

I am having an Calendar Event with start date as (24hrs format) 27-Apr-2016 11:00:00 and end date as 29-Apr-2016 11:00:00. I am having three timings 10:45:00, 10:30:00 and 10:15:00 which are calculated for alerting the event prior to the actual set timings (i.e 15 mins, 30 mins and 45 mins early to the start date).
Also the alarm must repeat daily for the same prior timings till the end date is reached.
Here is how i tried to do it, How ever the below code does not invoke the alarm nor it repeats daily
In the MainActivity.java
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, Broadcast.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 234324243, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.set(2016,03,27,11,00,00);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis()-(60000*15), pendingIntent); // subtract for 15 mins prior alarm time
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis()-(60000*30), pendingIntent); // subtract for 30 mins prior alarm time
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis()-(60000*45), pendingIntent); // subtract for 45 mins prior alarm time
In the Broadcast.java
Log.i("Alarm", "Alarm Manager is called");
Toast.makeText(context, new Date().toString(), Toast.LENGTH_SHORT).show();
How can I achieve this? Please help
Here is my sample code, Try this:
Modify the date and time as your need in the below code.
public static int REPEAT_NOTIFICATION1 = 201;
public static int REPEAT_NOTIFICATION2 = 202;
public static int REPEAT_NOTIFICATION3 = 203;
private void repeatNotification() {
final DateTime dateTime1 = DateTime.now();
dateTime1.hourOfDay().setCopy(7);
dateTime1.minuteOfHour().setCopy(30);
dateTime1.secondOfMinute().setCopy(00);
final Calendar calendarNotifiedTime1 = Calendar.getInstance();
calendarNotifiedTime1.set(Calendar.HOUR, dateTime1.getHourOfDay());
calendarNotifiedTime1.set(Calendar.MINUTE, dateTime1.getMinuteOfHour());
calendarNotifiedTime1.set(Calendar.SECOND, dateTime1.getSecondOfMinute());
calendarNotifiedTime1.set(Calendar.AM_PM, Calendar.AM);
final DateTime dateTime2 = DateTime.now();
dateTime2.hourOfDay().setCopy(12);
dateTime2.minuteOfHour().setCopy(30);
dateTime2.secondOfMinute().setCopy(00);
final Calendar calendarNotifiedTime2 = Calendar.getInstance();
calendarNotifiedTime2.set(Calendar.HOUR, dateTime2.getHourOfDay());
calendarNotifiedTime2.set(Calendar.MINUTE, dateTime2.getMinuteOfHour());
calendarNotifiedTime2.set(Calendar.SECOND, dateTime2.getSecondOfMinute());
calendarNotifiedTime2.set(Calendar.AM_PM, Calendar.PM);
final DateTime dateTime3 = DateTime.now();
dateTime3.hourOfDay().setCopy(6);
dateTime3.minuteOfHour().setCopy(30);
dateTime3.secondOfMinute().setCopy(00);
final Calendar calendarNotifiedTime3 = Calendar.getInstance();
calendarNotifiedTime3.set(Calendar.HOUR, dateTime3.getHourOfDay());
calendarNotifiedTime3.set(Calendar.MINUTE, dateTime3.getMinuteOfHour());
calendarNotifiedTime3.set(Calendar.SECOND, dateTime3.getSecondOfMinute());
calendarNotifiedTime3.set(Calendar.AM_PM, Calendar.PM);
Intent intent1 = new Intent(EmptyActivity.this, NotificationReceiver.class);
intent1.putExtra(NotificationReceiver.NOTIFICATION_MESSAGE, "Repeat " + dateTime1.getHourOfDay() + ":" + dateTime1.getMinuteOfHour() + ":" + dateTime1.getSecondOfMinute());
Intent intent2 = new Intent(EmptyActivity.this, NotificationReceiver.class);
intent2.putExtra(NotificationReceiver.NOTIFICATION_MESSAGE, "Repeat " + dateTime2.getHourOfDay() + ":" + dateTime2.getMinuteOfHour() + ":" + dateTime2.getSecondOfMinute());
Intent intent3 = new Intent(EmptyActivity.this, NotificationReceiver.class);
intent3.putExtra(NotificationReceiver.NOTIFICATION_MESSAGE, "Repeat " + dateTime3.getHourOfDay() + ":" + dateTime3.getMinuteOfHour() + ":" + dateTime3.getSecondOfMinute());
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(EmptyActivity.this, REPEAT_NOTIFICATION1, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(EmptyActivity.this, REPEAT_NOTIFICATION2, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(EmptyActivity.this, REPEAT_NOTIFICATION3, intent3, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(ALARM_SERVICE);
cancelNotification(REPEAT_NOTIFICATION1);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendarNotifiedTime1.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent1);
cancelNotification(REPEAT_NOTIFICATION2);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendarNotifiedTime2.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent2);
cancelNotification(REPEAT_NOTIFICATION3);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendarNotifiedTime3.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent3);
}
Cancel Notification:
public void cancelNotification(int requestCode) {
try {
Intent notificationIntent = new Intent(getApplicationContext(), NotificationReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), requestCode, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
BroadCast Receiver:
public class NotificationReceiver extends BroadcastReceiver {
public static String NOTIFICATION_MESSAGE = "notificationMessage";
public static int REPEAT_NOTIFICATION1 = 201;
public static int REPEAT_NOTIFICATION2 = 202;
public static int REPEAT_NOTIFICATION3 = 203;
Context context;
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
//Assume StartDate = yesterday.
DateTime startDate = DateTime.now().minusDays(1);
//Assume EndDate = tomorrow
DateTime endDate = startDate.plusDays(2);
DateTime today = DateTime.now();
if (today.isBefore(endDate) || today.isEqual(endDate)) {
String message = intent.getStringExtra(NOTIFICATION_MESSAGE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//Define sound URI
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent notificationIntent = new Intent(context, EmptyActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
final DateTime dateTime = DateTime.now();
int color = 0xffffaa00;
// int color1 = context.getColor(R.color.notificatinBackgroundColor);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.festi_push_message_small);
builder.setContentIntent(pendingIntent);
builder.setContentTitle("Notification Sample");
builder.setAutoCancel(true);
builder.setContentText(message + ", Current Time : " + dateTime.getHourOfDay() + ":" + dateTime.getMinuteOfHour() + ":" + dateTime.getSecondOfMinute());
builder.setSound(soundUri);
builder.setLights(Color.RED, 1000, 1000);
builder.setColor(color);
Notification notification = builder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(102938, notification);
} else {
cancelNotification(REPEAT_NOTIFICATION1);
cancelNotification(REPEAT_NOTIFICATION2);
cancelNotification(REPEAT_NOTIFICATION3);
}
}
public void cancelNotification(int requestCode) {
try {
Intent notificationIntent = new Intent(context, NotificationReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Manifest.xml
<receiver android:name=".NotificationReceiver" />

Android - alarm clock with Notification using AlarmManager

I'm creating an alarm clock using AlarmManager and I have some troubles:
How to stop sounding of notification when I open Notification?
How to make alarm for a certain day of week (or the whole week), not for the certain date?
private void restartNotify()
{
Calendar calendar = Calendar.getInstance();
// current Month - 1
calendar.set(Calendar.MONTH, 5);
calendar.set(Calendar.YEAR, 2015);
calendar.set(Calendar.DAY_OF_MONTH, 28);
calendar.set(Calendar.HOUR_OF_DAY, 1);
calendar.set(Calendar.MINUTE, 40);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.PM);
Intent timeIntent = new Intent(MainActivity.this, TimeNotification.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, timeIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
}
public class TimeNotification extends WakefulBroadcastReceiver
{
#Override
public void onReceive(final Context context, Intent intent)
{
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null) {
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
ringtone.play();
//this will send a notification message
ComponentName comp = new ComponentName(context.getPackageName(),
AlarmService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
public class AlarmService extends IntentService
{
private NotificationManager alarmNotificationManager;
public AlarmService() {
super("AlarmService");
}
#Override
public void onHandleIntent(Intent intent)
{
sendNotification("Wake Up! Wake Up!");
}
private void sendNotification(String msg)
{
alarmNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder alamNotificationBuilder = new NotificationCompat.Builder(
this).setContentTitle("Alarm").setSmallIcon(R.drawable.abc_btn_radio_material)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
alamNotificationBuilder.setContentIntent(contentIntent);
alarmNotificationManager.notify(1, alamNotificationBuilder.build());
}

Cancelling Alarm Manager in Android

I am having some problem when trying to cancel AlarmManager in Android. I am calling this retrieveBudget() onCreate:
public void retrieveBudget() {
txtDisplayMonthlyExpenses = (TextView) findViewById(R.id.txtDisplayMonthlyExpense);
txtDisplayBudget = (TextView) findViewById(R.id.txtDisplayBudget);
cbDisplayReminderNotify = (CheckBox) findViewById(R.id.cbDisplayReminderNotify);
cbDisplayReminderNotify.setEnabled(false);
DatabaseAdapter mDbHelper = new DatabaseAdapter(this);
mDbHelper.createDatabase();
mDbHelper.open();
TransactionRecController trc = new TransactionRecController(
mDbHelper.open());
currentMonthExpense = trc.getThisMonthDebit();
txtDisplayMonthlyExpenses.setText("$ "
+ formatter.format(currentMonthExpense));
BudgetController bc = new BudgetController(mDbHelper.open());
BudgetModel bm = bc.getBudget();
if (bm.getBudgetAmount() != 0 && bm.getReminderNotify() != null) {
budget = bm.getBudgetAmount();
txtDisplayBudget.setText("$ " + formatter.format(budget));
if (bm.getReminderNotify().equals("Y")) {
cbDisplayReminderNotify.setChecked(true);
} else {
cbDisplayReminderNotify.setChecked(false);
}
AlarmManager mgr = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = null;
if (bm.getReminderNotify().equals("Y")
&& currentMonthExpense > budget) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 1);
notificationCount = notificationCount + 1;
Intent notificationIntent = new Intent(context,
BudgetAlarm.class);
notificationIntent.putExtra("NotifyCount", notificationCount);
pi = PendingIntent.getBroadcast(context, notificationCount,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 60000, pi);
} else {
mgr.cancel(pi);
}
} else {
txtDisplayBudget.setText("No budget record yet");
}
mDbHelper.close();
}
And inside my budgetAlarm class, it just simply setting the notification. So my problem is it did execute the notification every minute. But after I changed my reminderNotify to "N" instead of "Y", it does not cancel the alarm manager. I wonder why is it so because after my update SQL statement, I am calling this retrieveBudget() again.
Thanks in advance.
EDIT
These are the codes where I update the budget part. I am calling the the retrieveBudget() once again when the Okay from dialogue box was clicked.
public void onEditBudgetClicked(View view) {
AlertDialog.Builder EditDialog = new AlertDialog.Builder(this);
EditDialog.setTitle("Edit Budget");
// Get the components from XML file
LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View dialogView = li.inflate(R.layout.edit_budget, null);
txtEditBudgetAmount = (EditText) dialogView
.findViewById(R.id.txtEditBudgetAmount);
cbEditReminderNotify = (CheckBox) dialogView
.findViewById(R.id.cbEditReminderNotify);
// Retrieve budget record
DatabaseAdapter mDbHelper = new DatabaseAdapter(this);
mDbHelper.createDatabase();
mDbHelper.open();
BudgetController bc = new BudgetController(mDbHelper.open());
BudgetModel bm = bc.getBudget();
if (bm.getBudgetAmount() != 0 && bm.getReminderNotify() != null) {
txtEditBudgetAmount.setText(Float.toString(bm.getBudgetAmount()));
if (bm.getReminderNotify().equals("Y")) {
cbEditReminderNotify.setChecked(true);
editReminderNotify = "Y";
} else {
cbEditReminderNotify.setChecked(false);
}
}
mDbHelper.close();
cbEditReminderNotify.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (cbEditReminderNotify.isChecked()) {
editReminderNotify = "Y";
} else {
editReminderNotify = "N";
}
}
});
EditDialog.setView(dialogView);
EditDialog.setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
onEditBudgetSubmitClicked();
dialog.dismiss();
retrieveBudget();
}
});
EditDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
EditDialog.show();
}
The value of notification count used while initializing the pending intent at the time creation and cancellation of the alarm manager should be same.
Use same value of requestFalg in the pending intent.
Replace this part:
AlarmManager mgr = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = null;
if (bm.getReminderNotify().equals("Y")
&& currentMonthExpense > budget) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 1);
notificationCount = notificationCount + 1;
Intent notificationIntent = new Intent(context,
BudgetAlarm.class);
notificationIntent.putExtra("NotifyCount", notificationCount);
pi = PendingIntent.getBroadcast(context, notificationCount,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 60000, pi);
} else {
mgr.cancel(pi);
}
with
AlarmManager mgr = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent(context,
BudgetAlarm.class);
PendingIntent pi = null;
if (bm.getReminderNotify().equals("Y")
&& currentMonthExpense > budget) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 1);
notificationCount = notificationCount + 1;
notificationIntent.putExtra("NotifyCount", notificationCount);
pi= PendingIntent.getBroadcast(context, 1,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 60000, pi);
} else {
pi= PendingIntent.getBroadcast(context, 1,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.cancel(pi);
}
if you changed the value of requestFlag (in your case notificationcount)while initializing the pending intent after launching the alarm, you won't be able to cancel it.
Use same value of requestFlag in the pending intent while creating and cancelling the alarm. Here, I am using 1.
Since you are changing the value of notificationFlag after launching the alarm manager, don't use notificationFlag as a requestFlag. Use a constant integer value as a requestFlag while initializing pi inside both if and else part.
pi= PendingIntent.getBroadcast(context, CONSTANT_INTEGER,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
check the link below:
PendingIntent getBroadcast (Context context, int requestCode, Intent intent, int flags)
http://developer.android.com/reference/android/app/PendingIntent.html#getBroadcast%28android.content.Context,%20int,%20android.content.Intent,%20int%29
AlarmManager mgr = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = null;
if (bm.getReminderNotify().equals("Y")
&& currentMonthExpense > budget) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 1);
notificationCount = notificationCount + 1;
Intent notificationIntent = new Intent(context,
BudgetAlarm.class);
notificationIntent.putExtra("NotifyCount", notificationCount);
pi = PendingIntent.getBroadcast(context, notificationCount,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 60000, pi);
} else {
notificationCount = notificationCount + 1;
Intent notificationIntent = new Intent(context,
BudgetAlarm.class);
notificationIntent.putExtra("NotifyCount", notificationCount);
pi = PendingIntent.getBroadcast(context, notificationCount,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mgr.cancel(pi);
}

Past notifications showing with current notifications

I am using the AlarmManager for repeating alarms. I've set repeating alarms for Mondays, Thursdays and Saturdays. The alarm shows correctly on Monday but when Thursday comes, it displays both notifications for Monday and Thursday together, and shows all three notifications on the Saturdays. How do I code it such that when the first alarm is done, it doesn't show on subsequent alarms in that same week, instead it goes to the next weeks?
EDIT1 - Code
MainActivity
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_settings:
EnableNoti();
return true;
}
return super.onOptionsItemSelected(item);
}
private void EnableNoti() {
Calendar calendar = Calendar.getInstance();
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
Calendar calendar3 = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, 1); // Sunday
calendar1.set(Calendar.DAY_OF_WEEK, 4); // Wednesday
calendar2.set(Calendar.DAY_OF_WEEK, 6); // Friday
calendar3.set(Calendar.DAY_OF_WEEK, 5); // Thursday
calendar3.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1); // First Thursday of
// Each Month
Date now = new Date(System.currentTimeMillis());
if (calendar3.getTime().before(now)) {
calendar3.add(Calendar.MONTH, 1);
} else if (calendar.getTime().before(now)) {
calendar.add(Calendar.HOUR, 168);
} else if (calendar1.getTime().before(now)) {
calendar1.add(Calendar.HOUR, 168);
} else if (calendar2.getTime().before(now)) {
calendar2.add(Calendar.HOUR, 168);
}
// Sunday
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
// Wednesday
calendar1.set(Calendar.HOUR_OF_DAY, 17);
calendar1.set(Calendar.MINUTE, 30);
calendar1.set(Calendar.SECOND, 0);
calendar1.set(Calendar.AM_PM, Calendar.PM);
// Friday
calendar2.set(Calendar.HOUR_OF_DAY, 17);
calendar2.set(Calendar.MINUTE, 30);
calendar2.set(Calendar.SECOND, 0);
calendar2.set(Calendar.AM_PM, Calendar.PM);
// Thursday
calendar3.set(Calendar.HOUR_OF_DAY, 22);
calendar3.set(Calendar.MINUTE, 0);
calendar3.set(Calendar.SECOND, 0);
calendar3.set(Calendar.AM_PM, Calendar.PM);
Intent myIntent = new Intent(TheBeginningEnglish.this,
MyReceiverEnglish.class);
pendingIntent = PendingIntent.getBroadcast(TheBeginningEnglish.this, 0,
myIntent, 0);
Intent myIntent1 = new Intent(TheBeginningEnglish.this,
MyReceiver1English.class);
pendingIntent1 = PendingIntent.getBroadcast(TheBeginningEnglish.this,
0, myIntent1, 0);
Intent myIntent2 = new Intent(TheBeginningEnglish.this,
MyReceiver2English.class);
pendingIntent2 = PendingIntent.getBroadcast(TheBeginningEnglish.this,
0, myIntent2, 0);
Intent myIntent3 = new Intent(TheBeginningEnglish.this,
MyReceiver3English.class);
pendingIntent3 = PendingIntent.getBroadcast(TheBeginningEnglish.this,
0, myIntent3, 0);
AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7,
pendingIntent); // every Sunday
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar1.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7,
pendingIntent1); // every Wednesday
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar2.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7,
pendingIntent2); // every Friday
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar3.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 31,
pendingIntent3); // every first Thursday
}
Receiver.java
public class MyReceiverEnglish extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Intent service = new Intent(context, MyAlarmServiceEnglish.class);
context.startService(service);
}
}
AlarmService.java
public class MyAlarmServiceEnglish extends Service {
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
private NotificationManager mManager;
Notification notification;
// Notification notification;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
onStartCommand(intent, 0, startId);
}
#SuppressWarnings({ "static-access", "deprecation" })
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mManager = (NotificationManager) this.getApplicationContext()
.getSystemService(
this.getApplicationContext().NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(),
TheBeginning1English.class);
if (currentapiVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
Notification notification = new Notification(
R.drawable.ic_launcher,
"Its Sunday!.",
System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent1 = PendingIntent
.getActivity(this.getApplicationContext(), 0, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(this.getApplicationContext(),
"Testing", "Its Sunday.",
pendingNotificationIntent1);
mManager.notify(0, notification);
} else {
PendingIntent pendingNotificationIntent1 = PendingIntent
.getActivity(this.getApplicationContext(), 0, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Test Test App")
.setContentText("Its Sunday!.")
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingNotificationIntent1)
.setSmallIcon(R.drawable.ic_launcher).build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
mManager.notify(0, notification);
}
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
Thats it,in the main activity, you will see four separate calendar variables, I had to create a Receiver,Receiver1,Receiver2,Receiver3, and AlarmService1,2,3. for each calendar, not the best way, but only thing I could figure. I added the:
Date now = new Date(System.currentTimeMillis());
if (calendar3.getTime().before(now)) {
calendar3.add(Calendar.MONTH, 1);
} else if (calendar.getTime().before(now)) {
calendar.add(Calendar.HOUR, 168);
} else if (calendar1.getTime().before(now)) {
calendar1.add(Calendar.HOUR, 168);
} else if (calendar2.getTime().before(now)) {
calendar2.add(Calendar.HOUR, 168);
}
I added the date part today, havent checked it out to know if it will work. Thanks for helping me with this!
How Alaram Service work?
it start as per your condition like you have set for day,week or any week day. so at every specified time set it receive command. like Notification,tone.
so in onStartServiceCommand() method. you have to apply logic for that.
so notification just comes once for that specific day.

Categories