chongzixin
chongzixin

Reputation: 1981

Android setAlarmClock triggering immediately

I created a simple application to try out setAlarmClock(). There is only a single button in the MainActivity, and it calls setAlarm when clicked.

The code is below.

MainActivity

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "alarmclock.MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void setAlarm(View view) {
        Context context = getApplicationContext();
        Intent intent = new Intent(context, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

        long nextTrigger = SystemClock.elapsedRealtime()+10*1000;
        Log.i(TAG, SystemClock.elapsedRealtime() + ": scheduling next alarm at " + nextTrigger);

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

        AlarmManager.AlarmClockInfo ac = new AlarmManager.AlarmClockInfo(nextTrigger, null);
        alarmManager.setAlarmClock(ac, pendingIntent);
    }
}

AlarmReceiver

public class AlarmReceiver extends BroadcastReceiver {
    private static final String TAG = "alarmclock.AlarmReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, SystemClock.elapsedRealtime() + " in AlarmReceiver onReceive()");
    }
}

I am basically triggering the alarm for 10seconds later, but for some reason it's triggering immediately.

2020-09-21 22:09:56.664 17910-17910/com.example.alarmclock I/alarmclock.MainActivity: 3362358: scheduling next alarm at 3372358
2020-09-21 22:09:56.687 17910-17910/com.example.alarmclock I/alarmclock.AlarmReceiver: 3362382 in AlarmReceiver onReceive()

If I use setExactAndAllowWhileIdle the same code seems to work fine. But I am specifically wanting to try out setAlarmClock.

Upvotes: 1

Views: 1249

Answers (2)

chongzixin
chongzixin

Reputation: 1981

It worked after I changed from SystemClock.elapsedRealtime() to System.currentTimeMillis().

long nextTrigger = System.currentTimeMillis()+10*1000

After reading the documentation in greater detail, I realise that the first parameter of the AlarmClockInfo constructor takes

long: time at which the underlying alarm is triggered in wall time milliseconds since the epoch

which is what System.currentTimeMillis() gives.

On the other hand, SystemClock.elapsedRealtime() returns the

time since the system was booted...

which will always be a much smaller number than wall time since epoch. As a result, the alarm gets scheduled immediately because

If the stated trigger time is in the past, the alarm will be triggered immediately.

Upvotes: 2

Pavneet_Singh
Pavneet_Singh

Reputation: 37404

The AlarmClockInfo requires a wall time:

time at which the underlying alarm is triggered in wall time milliseconds since the epoch

but you are using elapsedRealtime() time so use System.currentTimeMillis to fix the issue.

Upvotes: 4

Related Questions