I'm trying to make an an app that sends multiple scheduled alarms, shown through a notification according to a specific time (not time interval, but time) every day.
I already implemented the AlarmReceiver.class that fires the notifications at each intent, but the problem is that I don't get any notification. I tried to show a Log inside the onReceiver() method, but the message hasn't been shown, so the alarm hasn't been reached.
This is the setAlarm() function, that sets the hour and the time to the Calendar I instantiated:
public void setAlarm()
{
SharedPreferences pref = this.getSharedPreferences("NOTIFICATION_CODE", Context.MODE_PRIVATE);
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);
calendar.set(Calendar.HOUR_OF_DAY, picker_hour);
calendar.set(Calendar.MINUTE, picker_minute);
calendar.set(Calendar.SECOND, 0);
if(current.before(calendar))
{
calendar.add(Calendar.DATE, 1);
}
medName = mName;
medFormat = mFormat;
int _reqCode = pref.getInt("reqCode", -1);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this, _reqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
aManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
editor = pref.edit();
editor.putInt("reqCode", ++_reqCode);
editor.commit();
}
To set the time, I implemented a TimePickerDialog and I stored hour and minute values to picker_hour and picker_minute.
Since I have to send multiple alarms, I use SharedPreferences to store the reqCode used then to identify the PendingIntent every time one is sent.
This is the AlarmReceiver.class that fire a notification for each intent received. Every notification is identified through the same reqCode of the PendingIntent:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String[] data = AddMedicine.getData();
SharedPreferences pref = context.getSharedPreferences("NOTIFICATION_CODE", context.MODE_PRIVATE);
int reqCode = pref.getInt("reqCode", -1);
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(reqCode, notification);
Log.i("NOTIFICATION", "FIRED!");
}}
P.s. The alarm is set every time the user creates it, in order to schedule them through the reqCode.
So, anyone knows how to send multiple alarms according by time? Thank you in advance!
Related
I am developing the schedule notification for Android. It is successfully get notification at scheduled time but also get notification at the time when the application startup which I do not want. Here are my codes.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefs= PreferenceManager.getDefaultSharedPreferences(this);
show = (TextView)findViewById(R.id.textView);
View btn_failure = findViewById(R.id.btn_failure_id);
btn_failure.setOnClickListener(this);
View btn_unhappy = findViewById(R.id.btn_unhappy_id);
btn_unhappy.setOnClickListener(this);
View btn_chicken_soup = findViewById(R.id.btn_soup_id);
btn_chicken_soup.setOnClickListener(this);
View btn_no_motivation = findViewById(R.id.btn_no_id);
btn_no_motivation.setOnClickListener(this);
// createScheduledNotification(9,0);
}
#Override
protected void onResume() {
super.onResume();
time = prefs.getString("noti", "9:00");
String[] pieces=time.split(":");
hour = Integer.parseInt(pieces[0]);
minute = Integer.parseInt(pieces[1]);
boolean onOff = prefs.getBoolean("noti_10",true);
createScheduleNotification(hour,minute,onOff);
}
public void createScheduleNotification(int hour, int minute, boolean onOff){
if(onOff){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, getPendingIntent(this));
}else{
AlarmManager mgr=(AlarmManager)this.getSystemService(this.ALARM_SERVICE);
mgr.cancel(getPendingIntent(this));
}
}
private PendingIntent getPendingIntent(Context ctxt) {
Intent intent1 = new Intent(ctxt, TimeAlarm.class);
intent1.putStringArrayListExtra("quotes",quote_chicken_soup);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctxt, 0,intent1, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
public class TimeAlarm extends BroadcastReceiver {
private String daily_quote = "testing";
#Override
public void onReceive(Context context, Intent paramIntent) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(context,DisplayActivity.class);
intent.putStringArrayListExtra("quote",paramIntent.getStringArrayListExtra("quotes"));
daily_quote = paramIntent.getStringArrayListExtra("quotes").get(0);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
Notification.Builder builder = new Notification.Builder(context);
builder.setAutoCancel(true);
builder.setTicker("Daily Quote");
builder.setContentTitle("Daily Quote");
builder.setContentText(daily_quote);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
builder.setSubText("Be Happy! Have a nice day!"); //API level 16
}
Notification myNotication = builder.getNotification();
manager.notify(11, myNotication);
}
}
Where is the problem that cause the notification being push when app startup?
There seems nothing wrong in your code.
Issue with notification being pushed up at startup is surely because of AlarmManager code.
From your code snippet, I hard coded the setting of time as below, and it runs as expected . First time it triggers in one minute after the system clock and then every 2 minutes there after.
// first time set to-- trigger after one minute from now
long firstTimeTriggerAt = SystemClock.elapsedRealtime() + 1000 * 60 * 1;
AlarmManager am = (AlarmManager) MainActivity.this.getSystemService(MainActivity.this.ALARM_SERVICE);
//Repeat the alaram every two minutes
long interval = 1000 * 60 * 2;
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,firstTimeTriggerAt, interval, getPendingIntent(this));
So you need to check the constant values for time, which you are setting in Shared preference.
Just FYI , the code runs well with RTC_WAKEUP constant also.
Hope this helps.
in onResume() change
boolean onOff = prefs.getBoolean("noti_10",true);
to
boolean onOff = prefs.getBoolean("noti_10",false);
I want to make an app that sends scheduled notifications every day according to specific times inserted by the user.
The problem is that when I launch the app I get one or two notifications randomly and I don't receive them at the set time.
Here is my setAlarm() function called when the user clicks a button:
public void setAlarm()
{
String mName = NameFld.getText().toString();
String mFormat = FormatSpn.getSelectedItem().toString();
Date date = new Date();
Calendar calendar = new GregorianCalendar();
Calendar current = new GregorianCalendar();
current.setTime(date);
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, picker_hour);
calendar.set(Calendar.MINUTE, picker_minute);
calendar.set(Calendar.SECOND, 0);
if(current.before(calendar))
{
calendar.add(Calendar.DATE, 1);
}
medName = mName; // Used to build the notification (it doesn't matter for now).
medFormat = mFormat; // Used to build the notification (it doesn't matter for now).
long when = calendar.getTimeInMillis();
Intent intent = new Intent(AddMedicine.this, AlarmReceiver.class);
final int _id = (int) System.currentTimeMillis(); // PendingIntent id.
PendingIntent pIntent = PendingIntent.getBroadcast(AddMedicine.this, _id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
aManager.set(AlarmManager.RTC_WAKEUP, when, pIntent);
}
And here is my BroadcastReceiver class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String[] data = AddMedicine.getData(); // Used to build the notification (it doesn't matter for now).
// Notification building.
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(0, notification);
Log.i("NOTIFICATION", "The notification has been fired."); // Used to see if the alarm ha really been received.
}}
Can anyone elaborate something to fix this up? Thank you in advance for any help!
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 am using AlarmManager to set alarm and i want to save its id in my sqlite db, whenever i set the alarm, it fires immediately, i googled the solution, but did'nt find according to my requirement, may be i am getting wrong date and time from my date time picker widgets,
I am using date and time pickers as:
final DatePicker datePicker = (DatePicker)dialog.findViewById(R.id.datePicker);
final TimePicker timePicker = (TimePicker)dialog.findViewById(R.id.timePicker);
Then a dialoge appears, i change date and time, and then then get it as :
Calendar calendar = Calendar.getInstance();
calendar.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth(),
timePicker.getCurrentHour(), timePicker.getCurrentMinute(), 0);
timeSetForAlert = calendar.getTimeInMillis()/1000;
And then i pass this to service handler like,
Intent myIntent = new Intent(thisContext, MyReceiver.class);
myIntent.putExtra("timeSetForAlert", timeSetForAlert);
pendingIntent = PendingIntent.getBroadcast(thisContext, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, timeSetForAlert, pendingIntent);
I am skipping broadcast receiver here which takes intent and start alarm service, while alarm service is as:
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
long timeSetForAlert = intent.getLongExtra("timeSetForAlert", 0);
mManager = (NotificationManager) thisContext.getSystemService(thisContext.NOTIFICATION_SERVICE);
Intent intent1 = new Intent(thisContext,MainActivity.class);
Notification notification = new Notification(R.drawable.ic_launcher,"This is a test message!", timeSetForAlert);
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity( thisContext,0, intent1,PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(thisContext, "Notification..", "This is a test message!", pendingNotificationIntent);
mManager.notify(startId, notification);
Toast.makeText(thisContext, startId+"", Toast.LENGTH_SHORT).show();
}
Please suggest:
1) - Why alarm fires immediately
2) - where should i save it in my db
try using this
Calendar calendar = Calendar.getInstance();
calendar.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth(),
timePicker.getCurrentHour(), timePicker.getCurrentMinute(), 0);
timeSetForAlert = calendar.getTimeInMillis();//try without dividing with 1000
ya it can be solved like this.
accept both the answers..
code:
Instead of this
pendingIntent = PendingIntent.getBroadcast(thisContext, 0, myIntent,0);
PendingIntent pi = PendingIntent.getBroadcast(
getApplicationContext(), uniqueValue, intent, 0);
instead of "0" use unique value as second parameter to get multipleBroadcast.
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.