kotlinandroid-intentalarmmanager

Kotlin alarmManager.setExact() never fires


I have really tried to make this alarm work but it simply does not call the onReceive() in the AlarmReceiver class.. I have followed a million guides to no avail, and I have tried it in several API versions (24 and 34)

class MainActivity : ComponentActivity() {
    fun addAlarm() {
        val intent = Intent(this, AlarmReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(
            this,
            0,
            intent,
            PendingIntent.FLAG_IMMUTABLE)
        val timeToWakeupInMillis: Long = 3000//System.currentTimeMillis() + 3000
        val alarmManager = this.applicationContext.getSystemService(ALARM_SERVICE) as AlarmManager
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeToWakeupInMillis, pendingIntent)
    }

    // More functions here.
}

Here is the simple receiver class:

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Toast.makeText(context,"Alarm!",Toast.LENGTH_LONG).show()
    }
}

In AndroidManifest.xml I have the SCHEDULE_EXACT_ALARM permission:

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>

I DO have the code for requesting the permission but left it out above for brewity. It's working, it redirects the user to the Alarms & Reminders page, in short:

if (alarmManager.canScheduleExactAlarms() == false) {
  Intent().also { intent -> intent.action = ACTION_REQUEST_SCHEDULE_EXACT_ALARM

    this.startActivity(intent)
  }
}

Code runs fine, setExact() gets called with no exceptions, but onReceive() is never called. This drives me crazy, please help!


Solution

  • Did you register your receiver in AndroidManifest.xml:

    ...
      <application>
    
      ...
    
        <receiver
          android:name=".AlarmReceiver"
          android:exported="false">
    
            <intent-filter>
              <action android:name="YOUR_ACTION_NAME"/>
            </intent-filter>
    
        </receiver>
    
      </application>
    ...
    

    You should also specify action name when you create the intent for your alarm:

    fun addAlarm() {
      val intent = Intent(this, AlarmReceiver::class.java)
      intent.setAction("YOUR_ACTION_NAME")
      val pendingIntent = PendingIntent.getBroadcast(
        ...