Search code examples
androidandroid-intentandroid-manifestalarmmanagerreceiver

AlarmManager executes my PendingIntent immediately instead of waiting for sertain time


I am trying to implement an alarm, and therefore my app has 2 activities: main one (where the user sets an alarm) and the 'ringing' one which is displayed when the alarm is actually triggered. Here is how I send an intent for AlarmManager to call the 'ringing' window:

public void scheduleAlarm(View view) {
    Intent intent = new Intent(this, WakeUp.class);
    intent.setAction(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    PendingIntent wakeUp = PendingIntent.getActivity(this, 123, intent, 0);
    AlarmManager alarmManager = (AlarmManager) this.getSystemService(this.ALARM_SERVICE);
    alarmManager.setExact(AlarmManager.RTC_WAKEUP, calculateMillis(), wakeUp); // setExact is pretty much made for setting alarms anyway
}

private long calculateMillis() {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR, hour);
    cal.set(Calendar.MINUTE, minute);
    cal.set(Calendar.SECOND, 0);
    return cal.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
}

In my manifest I have the following:

    <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".WakeUpWithMath"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".WakeUp"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:label="@string/title_activity_wake_up"
        android:theme="@style/FullscreenTheme" >
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
        </intent-filter>

    </activity>
</application>

I have tested it multiple times and with different values for the calculateMillis (even mocked to return 30000) yet the result is always the same: right after calling alarmManager.setExactit displayes the 'ringing' activity and does not wait for the time to pass at first.

What have I missed? Is the manifest configured wrong? do I need to use a <receiver> tag? if so, how should I configure it?


Solution

  • setExact uses absolute time, not relative time. Use the time returned by cal.getTimeInMillis() without subtracting current time.