Search code examples
androidbroadcastreceiveralarmmanager

AlarmManager setEexact() not working


I have have two AlarmManager scheduled to fire once a day at 23:59 and another one that fires at the same time but once a week.

Below is the two functions that do this:

private fun midnightTimeClearCache(dataType: DataType, requestCode: Int) {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = System.currentTimeMillis()
        calendar.set(Calendar.HOUR_OF_DAY, 23)
        calendar.set(Calendar.MINUTE, 59)
        val intent = Intent(context, ClearDataReceiver::class.java)
        intent.putExtra(ClearDataReceiver.DATA_TYPE_EXTRA, dataType.name)
        val pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)

    }

    private fun weekTimeClearCache(dataType: DataType, requestCode: Int) {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = System.currentTimeMillis()
        calendar.set(Calendar.HOUR_OF_DAY, 23)
        calendar.set(Calendar.MINUTE, 59)
        var i: Int = calendar.get(Calendar.WEEK_OF_MONTH)
        calendar.set(Calendar.WEEK_OF_MONTH, i++)
        val intent = Intent(context, ClearDataReceiver::class.java)
        intent.putExtra(ClearDataReceiver.DATA_TYPE_EXTRA, dataType.name)
        val pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
    }

Below is the reciever that should get fired as part of the above pending Intents

class ClearDataReceiver : DaggerBroadcastReceiver() {
 override fun onReceive(context: Context?, intent: Intent?) {
        super.onReceive(context, intent)
        var bundle = intent!!.extras
        val dataTypeString = bundle.getString(DATA_TYPE_EXTRA)
        val dataType = DataType.valueOf(dataTypeString)
        Log.d("JJJ", "clearing data for " + dataTypeString)
        when (dataType) {
            DataType.CUSTOMER_DETAILS -> {
                storage.clearDetails()
                storageClearSchedular.setCustomerDetailsClear()
            }
            DataType.CUSTOMER_PIC -> {
                storage.clearPic()
                storageClearSchedular.setPicClear()
            }
}

here is my manifest:

And the boot reciever so i can reset the alerm manager

override fun onReceive(context: Context?, intent: Intent?) {
        Log.d("JJJ", "onReceive")

        storageClearSchedular = StorageClearSchedular(context!!, context!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager)
        storageClearSchedular.setAllSchedulars()

When i set the above alert manager schedules and then kill the app from the background before i head to bed, i then load up the app again to find that it diddnt execute my broadcast reciever(no details on the logs and data not cleared).

What should happen is that it should execute every dat at the time i set or once a week and then set it again after it has been fired but it doesnt seem to work at all.

I first tried setRepeating but that diddnt work as im targeting devices from api 19 and above

What am i missing?


Solution

  • For api version above 19 use this code

    if (Build.VERSION.SDK_INT < 19) {
    
    
               alarmManager.set(AlarmManager.RTC,
                    calendar.getTimeInMillis(), pendingIntent);
                 }
            } else if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT <= 22) {
                alarmManager.setExact(AlarmManager.RTC,
                        calendar.timeInMillis, pendingIntent)
            } else if (Build.VERSION.SDK_INT >= 23) {
                alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC,
                        calendar.timeInMillis, pendingIntent)
            }
    

    For the daily alarm, you can check the condition. This example will set alarm for 9 AM Daily. Also, you may need to set the alarm again when the device restarts or boots up because all the alarms get canceled once the device is powered off or restarted.

    Calendar calendar = Calendar.getInstance()
            // set selected time from timepicker to calendar
            calendar.setTimeInMillis(System.currentTimeMillis());
    
            // if it's after or equal 9 am schedule for next day
            if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 9) {
                Log.e("", "Alarm will schedule for next day!");
                calendar.add(Calendar.DAY_OF_YEAR, 1); // add, not set!
            }
            else{
                Log.e("", "Alarm will schedule for today!");
            }
            calendar.set(Calendar.HOUR_OF_DAY, 9);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);