Search code examples
androidkotlinandroid-servicealarmmanagerandroid-doze

Android Alarm Not Set


I used to set alarms using the following code-segment in other projects as repeating and non-repeating, but it's now driving me crazy about what may the silly mistake be that I've made for not the alarm speaking to my current implementation :\ :

private fun setAlarm(obj: MyObject, time: Long) {
    val intent = Intent(applicationContext, MyAlarmIntentService::class.java)
    intent.putExtra(C.KEY_ME, obj)

    val pendingIntent = PendingIntent.getService(applicationContext, 43, intent, 
                                          PendingIntent.FLAG_UPDATE_CURRENT)

    val context = this@MyActivity
    val cal = Calendar.getInstance()
    cal.timeInMillis = time * 1000   // time is in seconds
    Log.d("setAlarm", "setting time -> $time for obj = $obj")
    Log.d("setAlarm", "Set calendar: " + cal.toString())

    val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)  // Overriding doze-mode
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        val alarmClockInfo =
                AlarmManager.AlarmClockInfo(cal.timeInMillis, null)
        alarmManager.setAlarmClock(alarmClockInfo, pendingIntent)
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) // Overriding doze-mode
        // Not-working in Nexus 6 - API 25 (7.1.1), but works in API 23 (6.0.1, tested in multiple devices)
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 
                    cal.timeInMillis, pendingIntent) 
    else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) // Works
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.timeInMillis, pendingIntent)
    else // works
        alarmManager.set(AlarmManager.RTC_WAKEUP, cal.timeInMillis, pendingIntent)
}

The IntentService class is as the following:

class MyAlarmIntentService : IntentService("Notification") {

  override fun onHandleIntent(intent: Intent?) {
    val obj = intent?.getParcelableExtra<MyObj>(C.KEY_ME) ?: return
    Lg.d(TAG, "My alarm fired for - \n" + obj.toString())
  }

  companion object {
    private val TAG = ContestAlarmIntentService::class.java.simpleName
  }

}

The service is declared in manifest as:

<service android:name=".services.MyAlarmIntentService" />

The following is an example of the mentioned log inside setAlarm() method:

E/setAlarm: setting time -> 1514993850 for obj = MyObj{...}
E/setAlarm: Set calendar: java.util.GregorianCalendar[time=1514993850000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=libcore.util.ZoneInfo[id="Asia/Dhaka",mRawOffset=21600000,mEarliestRawOffset=23400000,mUseDst=false,mDstSavings=0,transitions=7],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2018,MONTH=0,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=3,DAY_OF_YEAR=3,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=9,HOUR_OF_DAY=21,MINUTE=37,SECOND=30,MILLISECOND=0,ZONE_OFFSET=21600000,DST_OFFSET=0]

This used to be a straight-forward code to me, but which fundamental may I be missing for these 3 days' of test sessions?


Solution

  • Sorry I did not go through all your code as I was busy in another task, so here's my code used with Broadcast

    Intent intent = new Intent(context, AlarmReceiver.class);
        intent.setAction(UtilAlarmConstants.ALARM_ACTION);
    pIBroadCast = PendingIntent.getBroadcast(context, ALARM_PI_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        alarmManager = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    
        if (alarmManager != null) {
    
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
              alarmManager.setExactAndAllowWhileIdle(ALARM_TYPE, calendar.getTimeInMillis(),pendingIntent);
    
            else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                AlarmManager.AlarmClockInfo alarmClockInfo
                        = new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + fireAT, null);
                alarmManager.setAlarmClock(alarmClockInfo, pIBroadCast);
            }
            //setExact for 19
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, fireAT, pIBroadCast);
            } else {
                alarmManager.set(AlarmManager.RTC_WAKEUP, fireAT, pIBroadCast);
            }
        }
    

    and Broadcast

        if (intent != null && intent.getAction() != null) {
    
            if (intent.getAction().equalsIgnoreCase(UtilAlarmConstants.ALARM_ACTION)) {
    
                setUpNotification(context, intent);}
    

    sorry for not giving answer related to service as they are all same wacky dacky :)