Ali Mehdi
Ali Mehdi

Reputation: 924

Why BroadcastReceiver is initializing on past time?

I am making an app which:

  1. Inputs from user a time range... (Initial time, Final time) suppose user gives (06:00 PM To 07:00 PM)
  2. When current time of the phone equals initial time then silent mode of the phone activates.

Everything working fine if the time range is of future (if my phone time is before 05:00PM in above case):

  1. Lets say My Phone current phone time is 08:00 PM and I have made time range from (06:00 PM To 07:00 PM). Then silent mode of the phone activates at my current time (08:00 PM). It should activate next day...

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

Answers (3)

Jude Fernandes
Jude Fernandes

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

rekire
rekire

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

NightFury
NightFury

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

Related Questions