I'm working on an app in which I need the user to schedule an event. I am using TimePicker and DatePicker Dialogs to set the time of the event and an AlarmManager with a BroadcastReceiver to execute the action when the time is reached. On testing I have come to a conclusion that my time and date picker dialogs are working fine and I am able to pick a date and time. However the BroadcastReceiver isn't being triggered by the AlarmManager when the time is reached.
Here is my MainActivity.class that schedules the event:
public class MainActivity extends Activity {
Button setTime;
Button scheduleEvent;
static final int DATEPICKER_DIALOG_ID = 0;
static final int TIMEPICKER_DIALOG_ID = 1;
int dpYear, dpMonth, dpDay, tpHour, tpMinute;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Calendar calendar = Calendar.getInstance();
dpYear = calendar.get(Calendar.YEAR);
dpMonth = calendar.get(Calendar.MONTH);
dpDay = calendar.get(Calendar.DAY_OF_MONTH);
tpHour = calendar.get(Calendar.HOUR_OF_DAY);
tpMinute = calendar.get(Calendar.MINUTE);
setTime = (Button) findViewById(R.id.button1);
scheduleEvent = (Button) findViewById(R.id.button2);
setTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showDialog(DATEPICKER_DIALOG_ID);
}
});
scheduleEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("com.ohs.example.myEvent");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmMgr = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, dpYear);
cal.set(Calendar.MONTH, dpMonth);
cal.set(Calendar.DAY_OF_MONTH, dpDay);
cal.set(Calendar.HOUR_OF_DAY, tpHour);
cal.set(Calendar.MINUTE, tpMinute);
cal.set(Calendar.SECOND, 0);
long mills = cal.getTimeInMillis();
alarmMgr.set(AlarmManager.RTC_WAKEUP, mills, pendingIntent);
Toast.makeText(this, "Event scheduled at " + tpHour + ":" + tpMinute + " " + dpDay + "/" + dpMonth + "/" + dpYear, Toast.LENGTH_LONG).show();
}
});
}
@Override
protected Dialog onCreateDialog(int id) {
if (id == DATEPICKER_DIALOG_ID) {
return new DatePickerDialog(this, datePickerListener, dpYear, dpMonth, dpDay);
} else if (id == TIMEPICKER_DIALOG_ID) {
return new TimePickerDialog(this, timePickerListener, tpHour, tpMinute, false);
} else {
return null;
}
}
private DatePickerDialog.OnDateSetListener datePickerListener =
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
dpYear = i;
dpMonth = i1 + 1;
dpDay = i2;
showDialog(TIMEPICKER_DIALOG_ID);
}
};
protected TimePickerDialog.OnTimeSetListener timePickerListener =
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
tpHour = i;
tpMinute = i1;
}
};
}
AlarmReceiver.class:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Broadcast Received", Toast.LENGTH_LONG).show();
eventMethod();
}
protected void eventMethod() {
//Do something...
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ohs.example" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver" android:enabled="true">
<intent-filter>
<action android:name="com.ohs.example.myEvent" />
</intent-filter>
</receiver>
</application>
</manifest>
I have previously worked on other apps where I had to set a repeating alarm for every 6 hours. I used the exact same code as above (with an AlarmManager and BraodcastReceiver), only instead of:
cal.set(Calendar.YEAR, dpYear);
cal.set(Calendar.MONTH, dpMonth);
cal.set(Calendar.DAY_OF_MONTH, dpDay);
cal.set(Calendar.HOUR_OF_DAY, tpHour);
cal.set(Calendar.MINUTE, tpMinute);
cal.set(Calendar.SECOND, 0);
All I had was:
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.HOUR_OF_DAY, 18);
And it works perfectly. So are the "YEAR", "MONTH", and "DAY_OF_MONTH" the ones that are causing problems here. If so, what's the solution?
I have looked a lot for solutions to my problem and I've found similar questions on stackoverflow, but none have helped me. Any help would be much appreciated.
After lots and lots of trying... I realized that the problem is that Calendar.DAY_OF_MONTH takes months starting from 0 to 11 (0 being Jan and 11 being December)... And I unfortunately did not know that, so I added 1 to the value of month obtained from the datePicker. So I just removed the + 1 and now it's working perfectly.