I want to trigger repeating alarm at specific time & I'm using below code but it does not trigger the alarm at the time I wanted.
boolean weeklyAlarmUp = (PendingIntent.getBroadcast(ctxt, 0, new Intent(ctxt, ScheduledWeeklyService.class), PendingIntent.FLAG_NO_CREATE) != null);
if (!weeklyAlarmUp) {
AlarmManager mgr = (AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(ctxt, ScheduledWeeklyService.class);
PendingIntent pi = PendingIntent.getBroadcast(ctxt, 0, i, 0);
Date date = null;
try {
date = (Date) formatter.parse("17-Mar-2014 13:10:00"); // This date & time will be an user input from some activity
} catch (ParseException e) {
e.printStackTrace();
}
long triggerWeeklyTaskAt = date.getTime();
long currentTime = System.currentTimeMillis();
// Don't trigger the alarm is input date time is in the past, set it to next day but at the same time
if (currentTime > triggerWeeklyTaskAt) {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 13);
c.set(Calendar.MINUTE,10);
c.set(Calendar.SECOND,0);
c.set(Calendar.MILLISECOND, 0);
c.add(Calendar.DATE, 1);
date = c.getTime();
triggerWeeklyTaskAt = date.getTime();
}
Locale locale = Locale.getDefault();
msgFormatter.setLocale(locale);
Object[] objs = { "Dummy" };
SchedulerLog.logInfo(ctxt, ctxt.getString(R.string.module_scheduler), msgFormatter.format(objs));
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, triggerWeeklyTaskAt, PERIOD_WEEKLY, pi);
}
Can anyone tell me what is wrong in below code? How can I check what time it'll trigger alarm at?
Thanks
Your outer if statement looks a bit weird. Are you sure execution is making it inside of it? Throw in a Log statement and/or step through the code to make sure.
If I understand your logic, you're attempting to not create a duplicate PendingIntent. So if the PI already exists, you bypass the whole body of the if. The problem with that is that your alarm setup is inside the if statement too.
The reference page says "...even if its owning application's process is killed, the PendingIntent itself will remain usable from other processes that have been given it." So perhaps a matching PI still exists from a previous run? It might be better to always (re)create the PI, but use FLAG_CANCEL_CURRENT or FLAG_UPDATE_CURRENT depending on whether you want to update the particulars.
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);
So I'm trying to make an AlarmManager that's suppose to launch at a specific time. The problem is that when I set the time, tt doesn't work. I think the main problem is that after I have change the time on Calendar, in logs object value "time" shows ?
timeOff = Calendar.getInstance();
System.out.println(timeOff);
timeOff.add(Calendar.DAY_OF_WEEK,Calendar.FRIDAY);
timeOff.set(Calendar.HOUR_OF_DAY, 16);
timeOff.set(Calendar.MINUTE, 30);
timeOff.set(Calendar.SECOND, 0);
System.out.println(timeOff);
System.out.println("TIME:: "+timeOff.getTimeInMillis());
Intent intent = new Intent(TabsActivity.this, Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(TabsActivity.this, 1122, intent, 0);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(am.RTC_WAKEUP, timeOff.getTimeInMillis(),timeOff.getTimeInMillis()+ 1000,pendingIntent);// + 604800000L,pendingIntent);
Logs shows this:
Before change:
java.util.GregorianCalendar[time=1406899765159,areFieldsSet=true,lenient=true,zone=Europe/Riga,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=7,WEEK_OF_YEAR=31,WEEK_OF_MONTH=1,DAY_OF_MONTH=1,DAY_OF_YEAR=213,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=29,SECOND=25,MILLISECOND=159,ZONE_OFFSET=7200000,DST_OFFSET=3600000]
After Change:
java.util.GregorianCalendar[time=?,areFieldsSet=false,lenient=true,zone=Europe/Riga,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=7,WEEK_OF_YEAR=32,WEEK_OF_MONTH=2,DAY_OF_MONTH=7,DAY_OF_YEAR=219,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=30,SECOND=0,MILLISECOND=159,ZONE_OFFSET=7200000,DST_OFFSET=3600000]
As you see the value -
Time=?
So my question, what am I doing wrong, why does after I have set the time, it doesn't show. And even if I try to log out plain timeOff.getTimeInMillis() , it doesn't show anything at all.
Solution
Change timeOff.add(Calendar.DAY_OF_WEEK,Calendar.FRIDAY) to timeOff.set(Calendar.DAY_OF_WEEK,Calendar.FRIDAY)
since calendar.add() method is abstract , you can use like this
Calendar timeOff = Calendar.getInstance();
System.out.println(timeOff);
timeOff.add(Calendar.DAY_OF_WEEK,Calendar.FRIDAY);
timeOff.getTime()
//System.out.println(timeOff.getTime());
timeOff.set(Calendar.HOUR_OF_DAY, 16);
timeOff.set(Calendar.MINUTE, 30);
timeOff.set(Calendar.SECOND, 0);
System.out.println(timeOff);
System.out.println("TIME:: "+timeOff.getTimeInMillis());
I am trying to achieve a task. Here is what's happening. I first save a value in the shared preference in a string from first activity and pass that value to this activity below. Then in my second activity, I call that value. Then I take the current time of the android and convert it to string.
=====================================================
#Lazy Ninja: UPDATED PLEASE CHECK: okay. I got the timings to match Finally! Now just one last thing, how do I keep running this "if statement" in the background so even if the app is closed, the system keeps checking for those two values?
=====================================================
UPDATED CODE:
Intent in = new Intent(Alarm.this, FajrAlarmRecieverActivity.class);
PendingIntent pi = PendingIntent.getActivity(Alarm.this, 2, in, PendingIntent.FLAG_CANCEL_CURRENT);
/*My Time from Shared Preference*/
//SharedPreferences prfs = getSharedPreferences("customeAlarmTimes", Context.MODE_PRIVATE);
//myTime = prfs.getString("Isha", "Isha");
String myTime = "11:15";
SimpleDateFormat formatter = new SimpleDateFormat("K:mm");
Date date = formatter.parse(myTime); // You will need try/catch around this
long millis = date.getTime();
/*My Time from Shared Preference*/
/*System Time*/
Date today = Calendar.getInstance().getTime();
String reportDate = new SimpleDateFormat("K:mm").format(today);
Date swag = formatter.parse(reportDate);
long currentTime= swag.getTime();
Log.d("SystemTime", reportDate);
Log.d("MyTime", myTime);
Log.d("SystemTime in Millis", currentTime+"");
Log.d("MyTime in Millis", millis+"");
if(millis == currentTime){
SendNotification();
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, AlarmManager.INTERVAL_DAY, pi);
}
else if (millis > currentTime){
Toast mtoast = Toast.makeText(getApplicationContext(), "FAJR TIME > CURRENT TIME", Toast.LENGTH_LONG);
mtoast.show();
}
else if (millis < currentTime){
Toast mtoast = Toast.makeText(getApplicationContext(), "FAJR TIME < CURRENT TIME", Toast.LENGTH_LONG);
mtoast.show();
}
}
}
Use repeating Alarm. It will handle the conditions for you
Try the following
Intent i = new Intent(getApplicationContext(), FajrAlarmRecieverActivity.class);
PendingIntent sender = PendingIntent.getActivity(Alarm.this, 0, i, 0);
// Get Time from your sharedpreferences
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour); // set Fajr hour
calendar.set(Calendar.MINUTE, minute); // set Fajr minute
calendar.set(Calendar.SECOND, 0); // set seconds ( well no need for seconds)
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
Dont forget to add FajrAlarmRecieverActivity in your manifest file.
After reading your comment just use set.
After the alarm fires, read from sharedPreferences and and set the alarm again.
EDIT
To get Current time
long currentTime= System.currentTimeMillis();
Get Time from your sharedPrefs, and convert it to milliseconds
if( sharedTimeInMillis < currentTime ){
// your good stuff
}
Convert your String time to milliseconds
myTime = prfs.getString("Isha", "Isha");
SimpleDateFormat formatter = new SimpleDateFormat("K:mm");
Date date = formatter.parse(myTime ); // You will need try/catch around this
long millis = date.getTime();
I have an app that needs to set alarms for multiple days of the week, depending on what days the user sets them. I have it working where it triggers an alarm at the appropriate time, but am wanting to know how to do multiple without them overridding the current AlarmManager. For example, here is my test code:
final int alarmid = (int)System.currentTimeMillis(); //creates unique id for the alarm attached to the object
tempmainfrag.mainObjectList.returnSchedule(i).setAlarmId(alarmid);
for(int j = 0; j < 7; j++)
{
if(tempmainfrag.mainObjectList.returnSchedule(i).returnDays()[j]) //if this day of the week has an alarm
{
int adjustedday = j+2; //makes time for DAY_OF_WEEK where sunday = 1, monday = 2, etc.
if (adjustedday == 8)
adjustedday = 1;
Calendar startcal = Calendar.getInstance();
startcal.set(Calendar.DAY_OF_WEEK, adjustedday);
startcal.set(Calendar.HOUR_OF_DAY, tempmainfrag.mainObjectList.returnSchedule(i).returnTimes()[0]);
startcal.set(Calendar.MINUTE, tempmainfrag.mainObjectList.returnSchedule(i).returnTimes()[1]);
startcal.set(Calendar.SECOND, 0);
Log.i("mydebug","Starting cal day of week: " + adjustedday);
Log.i("mydebug","Starting cal hour of day: " + tempmainfrag.mainObjectList.returnSchedule(i).returnTimes()[0]);
Log.i("mydebug","Starting minute: " + tempmainfrag.mainObjectList.returnSchedule(i).returnTimes()[1]);
Intent intent = new Intent(this, SilenceHandler.class);
intent.putExtra("starttime",tempmainfrag.mainObjectList.returnSchedule(i));
intent.putExtra("alarm_message", "Test!"); //FOR TESTING
PendingIntent pendintent = PendingIntent.getBroadcast(this, alarmid, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmman = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmman.setRepeating(AlarmManager.RTC_WAKEUP, startcal.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, pendintent);
// startcal.set(Calendar.MINUTE, (tempmainfrag.mainObjectList.returnSchedule(i).returnTimes()[1])+1);
// alarmman.setRepeating(AlarmManager.RTC_WAKEUP, startcal.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, pendintent);
}
}
The for loop iterates through days of the week, and at each iteration checks to see if the alarm should be set for that day. This code works (presumably), but to test if I could set another alarm on top of it I added in the last two lines of code that are commented out here. This makes the alarm go off a minute later, but not a minute earlier as well. I am doing this to demonstrate that if I want this code to work for multiple days of the week, the way the code is currently set up will just have the alarm set for the last day of the week that returns true. How can I make multiple alarms?
The problem is that although you are creating a unique ID for your PendingIntent, which would set separate alarms, in your test you are reusing the same PendingIntent, which would override your previous one. Create a new PendingIntent with a different alarmid to test this.
I'm having problem in scheduling my alarm. I want to make every call of my alarm unique so that it will not overlap the previous alarm that I've already set.
This is my code:
public void compareDates()
{
String callName;
String dateStart;
String dateDue;
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
long callTime = System.currentTimeMillis();
Date callsDateStart = new Date();
Date dateNow = new Date();
GlucoseDatabaseAdapter gda = new GlucoseDatabaseAdapter(this);
gda.open();
Cursor c = gda.getEntries(GlucoseDatabaseAdapter.TABLE_CALLS, null,null,null,null,null,null);
AlarmManager callsAlarm = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent alarmIntent = new Intent(this,callsNotify.class);
callAlarm = PendingIntent.getService(this, 0, alarmIntent, 0);
if(c.moveToFirst())
{
do
{
//GET DATA
callName = c.getString(GlucoseDatabaseAdapter.CALLS_NAME_KEY);
dateStart = c.getString(GlucoseDatabaseAdapter.CALLS_DATE_START_KEY);
dateDue = c.getString(GlucoseDatabaseAdapter.CALLS_DATE_DUE_KEY);
//COMPARE DATES
try
{
callsDateStart = sdf1.parse(dateStart); }
catch (ParseException e)
{ // TODO Auto-generated catch block
e.printStackTrace(); }
if(callsDateStart.after(dateNow))
{
long callsDs = callsDateStart.getTime();
long ff = callsDs - callTime;
callsAlarm.set(AlarmManager.RTC, System.currentTimeMillis() + ff, callAlarm);
}
}while(c.moveToNext()); }
// I'm calling callsAlarm multiple times in this code. When I set callsAlarm here it only sets the latest one. How do I make every set here unique?
You have to make sure the Intent you are passing in is unique or can only be called once. It looks like you are using the same one over and over so it is getting over written. You may want to change your pending intent to look like something as follows and read the android documentation for other possible flags to set
PendingIntent sender = PendingIntent.getBroadcast(con, 0, intent, PendingIntent.FLAG_ONE_SHOT);