Reputation: 924
I am making an app which:
Everything working fine if the time range is of future (if my phone time is before 05:00PM in above case):
I have made a service for this...
Whenever user enters range of time it starts a service onStart and onStartCommand are overridden...
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
ArrayList<HashMap<String, String>> arraylist_start = (ArrayList<HashMap<String, String>>) intent.getSerializableExtra("arraylist_start");
if(arraylist_start != null){
try {
silentModeOnBroadCastReceiver.startAlarmAt(this, arraylist_start);
silentModeOffBroadCastReceiver.startAlarmOff(this, arraylist_start);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
In arraylist_start i am taking list of time ranges from intent where user added time ranges... Same code is written in onStartCommand
In SilentModeOnBroadCastReceiver I have added startAlarmAt method which takes that ArrayList and calls pending intent
public void startAlarmAt(Context context, ArrayList<HashMap<String, String>> list) throws ParseException {
Calendar calendar = Calendar.getInstance();
for (int j = 0; j < list.size(); j++ ){
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
String timeStart = list.get(j).get("timeStart");
date1 = Calendar.getInstance();
date2 = Calendar.getInstance();
date1.setTime(dateFormat.parse(timeStart));
Log.i("Date1Time", date1.toString());
int hours = date1.get(Calendar.HOUR_OF_DAY);
int minutes = date1.get(Calendar.MINUTE);
calendar.set(Calendar.HOUR_OF_DAY, hours);
calendar.set(Calendar.MINUTE, minutes);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, SilentModeOnBroadCastReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, j, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, date1.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
}
}
Now in SilentModeOnBroadCastReceiver
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
// Put here YOUR code.
Toast.makeText(context, "Silent Activated !!!!!!!!!!", Toast.LENGTH_LONG).show();
Silent silent = new Silent(context);
silent.activateAudioMode(AudioManager.RINGER_MODE_SILENT);
wl.release();
}
Please help fix my problem... Why BroadcastReceiver is initializing on past time?
Upvotes: 0
Views: 133
Reputation: 7517
What it seems to be doing is getting the current time and setting an alarm for that.What i think you need to do is get the current time (now) and get the alarm time(alarm_time).You would need to consider days also while setting because if a user sets an alarm_time=06:00AM and now is 12:46PM you need to add a day to the alarm.
Upvotes: 1
Reputation: 47945
The reason for this behavior is that Android does not call it to the exact time (except you set some special flags). Android is doing that to improve the battery usage. This results that Android tries to invoke that alarm listeners as soon as possible for the given set of properties. Since your time window is up Android is late to invoke it so it does it best and calls it almost directly.
So just check if the window is in the past and if so add one day for the first call. I'm doing that in my app too, and it works fine.
You can add one day with this simple call:
if(calendar.before(GregorianCalendar.getInstance())) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
Upvotes: 1
Reputation: 13546
This is happening since you are setting alarm for the time, which has passed already. So android initializes broadcast receiver on current time. You need to check in code... if time has already passed, set it for next day.
Put this check before setting alarm:
if(alarm_time_in_ms < System.getCurrentTimeMillis())
{
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
Hope it helps!
Upvotes: 1