I am new to android programming. I am developing an app which has a local notification. I am using Alarmmanager to set a local notification.
When I set the same time to Alarmmanager onReceive is called once for that time. My pending intent is also different.
Here how I am setting alarm:
for(int i = 0; i < dosageDtoList.size();i++)
{
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
DosageDto dosageDto = dosageDtoList.get(i);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
String time = dosageDto.getReminderTime();
String dateTime = startDateStr + " " + time;
Date formattedDate = simpleDateFormat.parse(dateTime);
Calendar cal = Calendar.getInstance();
cal.setTime(formattedDate);
Intent notificationIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
notificationIntent.addCategory("android.intent.category.DEFAULT");
notificationIntent.putExtra(Constants.POS,i);
notificationIntent.putExtra(Constants.END_DATE, endDateStr);
notificationIntent.putExtra(Constants.TITLE, userDrugDto.getUserName());
notificationIntent.putExtra(Constants.SUB_TITLE, userDrugDto.getDrugName());
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent broadcast = PendingIntent.getBroadcast(context, i, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if(alarmManager != null)
{
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, broadcast);
}
}
Here is my Receiver class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// generating notification
}
}
If I set an alarm for these two dates and time
1. 01-June-2018 15:10
2. 01-June-2018 15:10
With different pending intent ideally onReceive should be called twice but it getting called once.
Am I missing something?
Related
This is the code to set u and delete the notifications. please let me know if you need more details. The only solutions on stack overflow are about the pending intent to be same. I already tried that solution and it didn't work.
public void setAlarm () throws java.text.ParseException {
RealmResults<Reminder> realmResults = getAllLatest();
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Reminder reminder = getLatestReminder(realmResults);
int hour = convertTimeToHoursAndMinutes(reminder.getReminderTime()).getHours();
int minutes = convertTimeToHoursAndMinutes(reminder.getReminderTime()).getMinutes();
PendingIntent pendingIntent = getPendingIntentFromReminder(reminder);
Log.v("Reminder is: ", String.valueOf(reminder));
Calendar calendar = Calendar.getInstance();
//calendar.setTimeZone(TimeZone.getTimeZone());
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minutes);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY , pendingIntent);
}
private PendingIntent getPendingIntentFromReminder(Reminder reminder) throws ParseException {
int hour = convertTimeToHoursAndMinutes(reminder.getReminderTime()).getHours();
int minutes = convertTimeToHoursAndMinutes(reminder.getReminderTime()).getMinutes();
Intent intent = new Intent(this, MyReceiver.class);
intent.setAction(reminder.getName());
Uri data = Uri.withAppendedPath(Uri.parse("TYS"),
String.valueOf(reminder.getId()));
intent.setData(data);
Calendar calendar = Calendar.getInstance();
//calendar.setTimeZone(TimeZone.getTimeZone());
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minutes);
//Log.v("Test", calendar.getTimeZone().toString());
// Log.v("Hours to show", String.valueOf(hour));
// Log.v("Minutes to show", String.valueOf(minutes));
intent.putExtra("reminderTitle", reminder.getName());
// Log.v("Reminder Name", reminder.getName());
intent.putExtra("notificationType", 1);
intent.putExtra("reminderId", String.valueOf(reminder.getId()));
intent.putExtra("reminderSubtitle", reminder.getSubTitle());
intent.setAction(Long.toString(System.currentTimeMillis()));
Log.v("set Alarm", String.valueOf(intent));
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
return alarmIntent;
}
public void deleteReminderIntent(Reminder reminder) throws ParseException {
Log.v("deleteReminderIntent", String.valueOf(reminder));
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent =getPendingIntentFromReminder(reminder);
alarmMgr.cancel(pendingIntent);
pendingIntent.cancel();
//alarmMgr.cancel(temp);
// alarmMgr.cancel(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
}
In getPendingIntentFromReminder() you set the ACTION in the Intent to the current time. When you call the method to get a PendingIntent to cancel your alarm, the current time is different, so the ACTION will not match the PendingIntent you have used to set the alarm.
In order to cancel the alarm, you need to use an Intent that will match the Intent that you used to set the alarm. The following parameters in the Intent must match:
ACTION
CATEGORY
DATA
COMPONENT
Any "extras" in the Intent are ignored, so they do not need to match.
For more details see https://stackoverflow.com/a/29590084/769265 and
Is it possible to create multiple PendingIntents with the same requestCode and different extras?
I am currently trying to create a repeating alarm that goes off at the same time everyday following a tutorial however I cannot seem to get it working. It goes off but as soon as the application launches instead of the set time I am not sure what the reason is. I also made sure the service was declared in manifest. Any idea where I am going wrong or if this the right way to go about something like this?
Main acitivty
public class MainActivity extends AppCompatActivity {
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
int i = preferences.getInt("numberofLaunces", 1);
if (i < 2) {
alarmMethod();
i++;
editor.putInt("numberoflaunches", i);
editor.commit();
}
if (savedInstanceState == null) {
return;
}
}
private void alarmMethod() {
Intent myIntent = new Intent(this, NotifyService.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 32);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.set(Calendar.DAY_OF_MONTH, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pendingIntent);
Toast.makeText(MainActivity.this, "start Alarm", Toast.LENGTH_LONG).show();
}
}
Notifyservice
public class NotifyService extends Service {
#Override
public IBinder onBind(Intent Intent) {
return null;
}
#Override
public void onCreate(){
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationManager mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent1,0);
Notification mNotify = new Notification.Builder(this)
.setContentTitle("placeholder tital")
.setContentText("Placeholder text")
.setSmallIcon(R.drawable.ic_cat)
.setContentIntent(pIntent)
.setSound(sound)
.addAction(0,"hello", pIntent)
.build();
mNM.notify(1, mNotify);
}
}
From developer [site](http://developer.android.com/reference/android/app/AlarmManager.html#set(int, long, android.app.PendingIntent))
The alarm is an Intent broadcast that goes to a broadcast receiver that you registered with registerReceiver(BroadcastReceiver, IntentFilter) or through the tag in an AndroidManifest.xml file.
You should define broadcast pending intent instead of service.
Change this
Intent myIntent = new Intent(this, NotifyService.class);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
To this
Intent myIntent = new Intent(this, MyAlarmBroadcastReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
Then implement MyAlarmBroadcastReceiver extends BroadcastReceiver class and fire notification inside onReceive().
The problem is quite simple: If the time a alarm should fire (the second parameter in setRepeating()) is in the past, it will fire immediately. The time you specified is 0:32 am in the night of the 0th (?) day of the month.
This is always in the past (maybe except for 32 minutes every month, though I don't know what the 0th day of the month is).
To fire the alarm every 24 hours at the time of 0:32 am use something like this:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 32);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
calendar.add(Calendar.DAY_OF_MONTH, new Date().after(calendar.getTime()) ? 1 : 0); //if the current time is after 0:32 am, one day is added
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24, pendingIntent);
I'm trying to make an app that fires notifications every time the user has to take a medicine.
ISSUE: I want to send a notification at a specific time. I searched on the Internet but I only found tutorials that explain how to send notifications after a specified interval of time. I have more times stored in an SQLite database and I want to fire a notification for every of them, like an alarm clock.
This is my setAlarm() function (If something is not clear, please ask):
public void setAlarm()
{
String mName = NameFld.getText().toString();
String mFormat = FormatSpn.getSelectedItem().toString();
Date date = new Date();
Calendar calendar = Calendar.getInstance();
Calendar current = Calendar.getInstance();
current.setTime(date);
calendar.setTime(date);
char[] sTime = TimeBtn.getText().toString().toCharArray();
if(sTime[0] == '0')
{
calendar.set(Calendar.HOUR_OF_DAY, sTime[1]);
}
else
{
String tmp = "";
tmp += sTime[0];
tmp += sTime[1];
int hour = Integer.parseInt(tmp);
calendar.set(Calendar.HOUR_OF_DAY, hour);
}
if(sTime[3] == '0')
{
calendar.set(Calendar.MINUTE, sTime[4]);
}
else
{
String tmp = "";
tmp += sTime[3];
tmp += sTime[4];
int minute = Integer.parseInt(tmp);
calendar.set(Calendar.MINUTE, minute);
}
calendar.set(Calendar.SECOND, 0);
if(current.before(calendar))
{
calendar.add(Calendar.DATE, 1);
}
Intent intent = new Intent(this, AlarmReceiver.class);
medName = mName;
medFormat = mFormat;
PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
aManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
}
This function splits the date in hour and minute values and sets them to the Calendar. Once running I get notifications with no title and text (I manage them in a static function that sends medicine data to the BroadcastReceiver class) and when I add a new alarm, it doesn't fire. Like I said before, I'd like to get notifications for each time value.
This is the BroadcastReceiver class:
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
String[] data = AddMedicine.getData();
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setAutoCancel(true);
builder.setTicker("It's pill time!");
builder.setContentTitle(data[0]);
builder.setContentText(data[1]);
builder.setSmallIcon(R.drawable.ic_launcher);
Notification notification = builder.build();
NotificationManager nManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
nManager.notify(AddMedicine.NOTIFICATION_ID, notification);
AddMedicine.NOTIFICATION_ID++;
}
}
If anyone could solve my problem, I will really appreciate it. Thanks in advance!
EDIT: This is the getData() method, that provides name and format of the medicine in order to put them in the building of the notification:
public static String[] getData()
{
String[] data = {medName, medFormat};
return data;
}
medName and medFormat are global variables initialized inside the setAlarm() method.
You are using same REQUEST_CODE for your PendingIntent, which replacing other PendingIntent's.
Use different request codes (2nd parameter) for your PendingIntent.getBroadcast() method for every call.
You can use SharedPref to store one counter which will increment for each PendingIntent.
Example :-
int reminderRequestCode = sPrefs.getInt(KeyConstants.PREF_REMINDER_REQUEST_CODE, -1);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
*reminderRequestCode*, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
SharedPreferences.Editor editor = sPrefs.edit();
editor.putInt(KeyConstants.PREF_REMINDER_REQUEST_CODE, ++reminderRequestCode);
editor.commit();
when I add a new alarm, it doesn't fire
You have to use a unique identifier (requestCode field of getBroadcastmethod) for each PendingIntent because you're using the same one ( 0 ) for all of the instances with the PendingIntent.FLAG_UPDATE_CURRENT so only the last created one will be fired.
I get notifications with no title and text
I think you have to use Intentextras to send datas to the AlarmReceiver because in your case data are changin before AlarmReceiver gets fired so you get wrong values.
I need help. Im new to android coding.
I have made task list, which I want to do specific things at time written in task.
Here is my task item
private long id;
private int mon;
private int tues;
private int wednes;
private int thurs;
private int fri;
private int satur;
private int sun;
private int profile;
Where I have days (monday,tuesday etc) which holds amount of minutes (for 10:00 its 600).
Following some tutorials I have alarm reciever
public class AlarmReciever extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Intent newIntent = new Intent(context, AlarmActivity.class);
newIntent.putExtra("profile", message);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
Its still unedited...
And then there is code which calls to make new tasks in alarm manager
// get a Calendar object with current time
Calendar cal = Calendar.getInstance();
// add 5 minutes to the calendar object
cal.add(Calendar.MINUTE, 5);
Intent intent = new Intent(ctx, AlarmReceiver.class);
intent.putExtra("alarm_message", "O'Doyle Rules!");
// In reality, you would want to have a static variable for the request code instead of 192837
PendingIntent sender = PendingIntent.getBroadcast(this, 192837, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
I dont understand how to specify in calendar, that I need new task repeating (for example) every monday at 10:00, and that when this happens, it calls new function, giving it "profile" variable to work with.
private void setProfile(Integer profile)
{
// Doing things with profile
}
take a look at the following code:
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent2 = new Intent(context, SampleAlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent2, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// Set the alarm's trigger time to item hour
calendar.set(Calendar.HOUR_OF_DAY, NuevoItemActivity.hora.getCurrentHour());
calendar.set(Calendar.MINUTE, NuevoItemActivity.hora.getCurrentMinute());
// Set the alarm to fire , according to the device's clock, and to repeat once a day.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, (PendingIntent) alarmIntent);
As you can see in last line, you are able to indicate AlarmManager.INTERVAL_DAY to repeat the PendingIntent.
I am trying this code to popup the alarm message. Its working when launching or opening the app, but it doesn't say any popup message while outside of the app.
I am so confused, i don't know what i am doing wrong.
String alarmtime = cur.getString(cur.getColumnIndex(DBDATA.LG_ALARMTIME));
//Reminder
String[] timesplit = alarmtime.split(":");
int hour = Integer.parseInt(timesplit[0]);
int minute = Integer.parseInt(timesplit[1]);
System.out.println(hour);
System.out.println(minute);
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, ShortTimeEntryReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar alarm = new GregorianCalendar();
alarm.setTimeInMillis(System.currentTimeMillis());
alarm.set(Calendar.HOUR_OF_DAY, hour);
alarm.set(Calendar.MINUTE, minute);
alarm.set(Calendar.SECOND, 0);
System.out.println(System.currentTimeMillis());
System.out.println(alarm.getTimeInMillis());
if (System.currentTimeMillis() > alarm.getTimeInMillis()){
alarm.setTimeInMillis(alarm.getTimeInMillis()+ 24*60*60*1000);// Okay, then tomorrow ...
alarmMgr.set(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(),pendingIntent);
}
else
{
alarmMgr.set(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(),pendingIntent);
}
I need to pop up the alarm message outside of the app(i.e) exactly like the alarm does.
Thanks for your help guys,
You probably need a BroadcastReceiver.
As you can read in this question : BroadcastReceiver not receiving an alarm's broadcast
You have to build the intent like this :
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(this, "CHECK_ALARM_CODE", alarmIntent, 0);
And receive the alarm like this :
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();
Log.d("OK", "AlarmReceiver.onReceive");
}
}
Don't forget to register your broadcast in your manifest file.