I am trying to make an alarm application that takes multiple "n" time inputs from the user and rings at those particular times. For that I have created an array of EditTexts for both the hour and minute entries. In the onclick listener for the start button, I wish to have alarm managers for all the entered time inputs initialized.
After creating an array of calendar, should i create an array of intents and pending intents and alarm manager objects also--one each for each calendar object?
This is the code for my start button:
public void setAlert(View view) {
int length = editHour.length;
int h[] = new int[length];
int m[] = new int[length];
Calendar[] cal = new Calendar[length];
for (int i = 0; i < length; i++) {
cal[i] = Calendar.getInstance();
}
for (int i = 0; i < length; i++) {
try {
m[i] = Integer.parseInt(editHour[i].getText().toString());
h[i] = Integer.parseInt(editMinute[i].getText().toString());
cal[i].set(Calendar.HOUR, h[i]);
cal[i].set(Calendar.MINUTE, m[i]);
Intent intent = new Intent(this, AlarmService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
12345, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,
cal[i].getTimeInMillis(), pendingIntent);
Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
} catch (Exception ex) {
ex.printStackTrace();
System.out.print("OOPS!");
}
}
}
your request code is unique and this is your problem. you must use unique code for your different alarms. your code with one request code override alarm time. (sorry for my bad english, it is not my language!)
use this code:
for (int i = 0; i < length; i++) {
.
.
.
int requestCode = (int) (System.currentTimeMillis());
PendingIntent pendingIntent = PendingIntent.getActivity(this,
requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Thread.sleep(10);
.
.
.
}
If you want 5 different alarms then your PendingIntent should be different. You can make a PendingIntent unique by putting an extra in it. but anyway, your code should at least generate one alarm. Verify that the time you are setting in the calendar is correct.
Anyway, you don't need 5 separate calendars, intents or anything. just update them and set the alarm. you definitively don't need to save them in an array.
Related
I am new to android ,here I am developing an alarm app for my working knowledge .
I have completed the following :
creating alarms and storing it into sqlite database.
Fetching all the alarms which has the status as active .
I have tried many stackoverflow post and their solutions and other blog posts which related to my doubt but I can't get a solution for my problem .
What is my problem is I am receiving number of alarm timings from sqlite database which I have set it before and I want to set all the alarms on the stored time .
Here I don't know how to set it .
Can anyone help me to set the multiple alarms .
I am really looking for someone's help to learn and experience these things please help me .
Thanks.
You need Alarm Manager and Pending Intent more.
for (int i = 0; i < ActivemyAlarms.size(); i++) {
int mHour = 0,mMin=0;
String amPm = null;
int mAlarmId = ActivemyAlarms.get(i).getALARM_ID(); //each alarm has an unique Id ,for differentiate one from another
String mAlarmTime = ActivemyAlarms.get(i).getALARM_TIME(); // alarm time (11:12:AM)
if (!(mAlarmTime == null)) {
String mtime = mAlarmTime; // alarm time format is 12hr format (ex : 11:12:AM)
String[] time = mtime.split(":");
mHour = Integer.parseInt(time[0].trim()); // get 11 hour
mMin = Integer.parseInt(time[1].trim()); // get 12 min
amPm = ((time[2].trim()));
}
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.HOUR_OF_DAY, amPm!=null && amPm.equalsIgnoreCase("pm")?(mHour+12):mHour);
calendar.set(calendar.MINUTE, mMin);
calendar.set(calendar.SECOND, 0);
calendar.set(calendar.MILLISECOND, 0);
Intent intent = new Intent(this,AlarmReceiver.class); //calling my Alarm service class which plays a music on the specific time
final int _id = (int) System.currentTimeMillis(); // get calendar instance
//Use Alarm manager and Pending Intent
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, mAlarmId, intent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
}
And to cancel any Alarm call alarmManager.cancel(PendingIntent) like;
Intent intent = new Intent(this,AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, mAlarmId, intent, 0);
alarmManager.cancel(alarmIntent);
I am currently debugging an issue with notifications inside my application. For some context, what I'd like to do is schedule notifications that should popup whenever a rocket launch is occurring. What I was doing was, after getting a list of scheduled launches from an API, I would take the launch date (in milliseconds since Jan 1 1970) and subtract the System.currentTimeMillis() from it. I would then use the resulting time to schedule the notification in the future, represented as System.currentTimeMillis() + timeDifference. I noticed that for whatever reason, only 1 notification is ever displayed.
I've tried debugging by scheduling notifications at 2, 4, and 6 minutes in the future, however a notification is only displayed at the 6 minute mark.
Some relevant code is below:
public void scheduleNotifications(List<Launch> launches) {
for(int i = 0; i < launches.size(); i++) {
SimpleDateFormat format = new SimpleDateFormat("MMMM dd, yyyy HH:mm:ss z");
Date date = null;
try {
date = format.parse(launches.get(i).getWindowstart());
} catch (ParseException e) {
e.printStackTrace();
}
long timeBetween = date.getTime() - System.currentTimeMillis();
Integer id = Long.valueOf(date.getTime()).intValue();
Intent notificationIntent = new Intent(this, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, id);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, getNotification(launches.get(i).getRocket().getName(), launches.get(i).getLocation().getPads().get(0).getName()));
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//Debug. Schedule at 2, 4, 6 minutes.
if (i == 0) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 120000, pendingIntent);
}
if (i == 1) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 240000, pendingIntent);
}
if (i == 2) {
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 360000, pendingIntent);
}
}
}
private Notification getNotification(String rocketName, String padName) {
Notification.Builder builder = new Notification.Builder(this);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
builder.setContentIntent(pendingIntent);
builder.setContentTitle("Upcoming Launch");
builder.setContentText("A launch of a " + rocketName + " is about to occur at " + padName + ". Click for more info.");
builder.setSmallIcon(R.drawable.rocket_icon);
return builder.build();
}
Broadcast Receiver:
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(id, notification);
}
}
I'd like to know why only a single notification is ever presented, as well as what I need to add to achieve the previously stated goal.
When you set an alarm using AlarmManager, it automatically cancels any existing alarm that has a matching PendingIntent. Since all your PendingIntents contain the same components, every time you set an alarm, the previously set ones are automatically cancelled.
If you want to set multiple alarms, you must make sure that each of the PendingIntents is unique. You can do this in one of the following ways:
Use a different requestCode (second parameter to PendingIntent.getBroadcast()) for each PendingIntent
Use a different ACTION in the Intent you pass to PendingIntent.getBroadcast() for each PendingIntent
I have two time picker and spinner with value 1 to 10, I want to make number of local notification selected from spinner between time selected from two time picker for eg from 2 pm to 6 pm I want to show six notification and it should notify every day between selected time range with selected value, I have used alarm manager for this but it showing just one notification also used set repeating.
Also I tried to first find time difference from two picker in millis and applied some logic but nothing seems to be good. Please give me some logic or sample code will be appreciated.
Some code snippet is
Intent myIntent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
myIntent, 0);
long next = 0;
for (int i = 0; i < spinnervalue ); i++) {
Log.e("checkkkk ", "" + "checkkkk");
alarmManager.set(AlarmManager.RTC_WAKEUP, next, pendingIntent);
next += diff_millis;
}
This snippet should work, perhaps with a few changes.
Here i am getting the difference between the 2 time pickers in milliseconds and += to the current time in milliseconds. Giving each pending intent a different ID and telling it to update and existing one if available (allows you to reset them if you know the ID (counter).
You have to divide the difference by the spinner chosen in order to get evenly spaced millisecond differences.
//Assume timepicker2 > timepicker1
int hours1 = timePicker1.getCurrentHour();
int minutes1 = timePicker1.getCurrentMinute();
int hours2 = timePicker2.getCurrentHour();
int minutes2 = timePicker2.getCurrentMinute();
int hourDiff = hours2-hours1;
int minutesDiff = minutes2-minutes1
int millisecondsDiff = hourDiff*60*60*1000;
millisecondsDiff += minutesDiff*60*1000;
Double period_diff = millisecondsDiff/spinnerValue;
//This is for the intent difference
int counter = 0;
long next = System.currentTimeMillis() + period_diff;
for (int i = 0; i < spinnervalue ); i++) {
Intent myIntent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, counter++, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Log.e("checkkkk ", "" + "checkkkk");
alarmManager.set(AlarmManager.RTC_WAKEUP, next, pendingIntent);
next += period_diff;
}
Don't take the snippet to work definitively as it's a quick jot down, but it should give you a general idea of where you should be looking.
Another idea would be to use i as the counter so you know in what range the IDs are.
http://developer.android.com/reference/android/app/AlarmManager.html#set%28int,%20long,%20android.app.PendingIntent%29
If the stated trigger time is in the past, the alarm will be triggered
immediately. If there is already an alarm for this Intent scheduled
(with the equality of two intents being defined by
filterEquals(Intent)), then it will be removed and replaced by this
one.
So setting this in a loop isn't what you want.
Your value for millis needs to be a time. 0 would indicate epoch (January 1st, 1970). What you probably want is "SystemClock.elapsedRealtime() + someValue" passed in for that parameter.
I'm making an app that stores medicines data in an SQLite database in order to send to the user notifications when it's time to take them.
I already created the BroadcastReceiver class and managed the notification Intent.
The Calendar.set() function is called when I add the time (hh:mm:ss) in the database but the problem is that every time I set the time in the TimePicker dialog, the notification is sent instantly, at regardless from time.
Here is the setAlarm function from the activity where I store the time and the other stuff:
public void setAlarm()
{
String mName = NameFld.getText().toString();
String mFormat = FormatSpn.getSelectedItem().toString();
Calendar calendar = Calendar.getInstance();
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);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("mName", mName);
intent.putExtra("mFormat", mFormat);
sendBroadcast(intent);
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);
The two lines of code below:
String mName = NameFld.getText().toString();
String mFormat = FormatSpn.getSelectedItem().toString();
Just takes data from the EditText fields then put in an Intent to manage them in the notification building.
In order to set the time to the Calendar variable, I take the text from the TimeBtn button that consists in the time string itself. I just set it when I pick the time from the TimePicker dialog.
Then I cast it in a char array in order to split hour and minute values and I put them in the calendar.set() function, distinguishing if the value starts with 0 to avoid an octal conversion when I cast them to int.
Once the time has been set, the AlarmReceiver class (extends BroadcastReceiver) does the following:
#Override
public void onReceive(Context context, Intent intent) {
String mName = intent.getStringExtra("mName");
String mFormat = intent.getStringExtra("mFormat");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setAutoCancel(true);
builder.setTicker("It's pill time!");
builder.setContentTitle(mName);
builder.setContentText(mFormat);
builder.setSmallIcon(R.drawable.ic_launcher);
Notification notification = builder.build();
NotificationManager nManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
nManager.notify(0, notification);
}
There aren't compilation errors, I just can't spot the issue.
Thanks in advance for any help!
Try replacing
aManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
with
aManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+calendar.getTimeInMillis(), pIntent);
Hi I am trying to create multiple alarms.
I am getting the number of hours left in the day, dividing it by the number of alarms needed, then trying to set alarms with intervals between them.
So for example if num of alarms is 2, and user clicks button at 14:00 there are 10 hours left, so 10 hours / 2 alarms = 5 hours distance between each alarm
So I want to set 2 alarms (one alarm at 19:00 and another at 24:00)
Currently my code is only setting 1 alarm and seems to ignore running the for loop multiple times. I'm not sure why the for loop dosnt create multiple alarms
try {
// Current Time
Time timeNow = new Time();
timeNow.setToNow();
int timeNowHour = timeNow.hour;
int timeNowMins = timeNow.minute;
// Hours left in day
int hoursInADay = 24;
int hoursLeftInDay = hoursInADay - timeNowHour;
// Number of alarms
int numAlarms = 2;
// Calc time between each alarm
int alarmDistance = hoursLeftInDay / numAlarms;
for(int i = 0; i < numAlarms; i++){
int alarmHour = timeNowHour + alarmDistance * (i+1);
Intent alarmIntent = new Intent(AlarmClock.ACTION_SET_ALARM);
alarmIntent.putExtra(AlarmClock.EXTRA_MESSAGE, "TEST ALARM");
alarmIntent.putExtra(AlarmClock.EXTRA_HOUR, alarmHour);
alarmIntent.putExtra(AlarmClock.EXTRA_MINUTES, timeNowMins);
alarmIntent.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(alarmIntent);
}
} catch (Exception e) {
}
Thanks
AlarmManager alarmManager= (AlarmManager)getSystemService(ALARM_SERVICE);
PendingIntent intent=createPendingResult(ALARM_TIME_ID, new Intent(), 0);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,SystemClock.elapsedRealtime() + alarmDistance,alarmDistance, intent);
And in the onActivityMethod you can do whatever you want.
Example:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ALARM_TIME_ID) {
Toast.makeText(this, "Alarm is running", Toast.LENGTH_LONG).show();
}
Make sure to set the ALARM_TIME_ID to a unique int value.