To solve this issue create a timestamp for minDate just before instantiation of DatePickerDialog:
private void showDatePicker(){
long now = System.currentTimeMillis();
DatePickerDialog datePickerDialog = new DatePickerDialog(
getActivity(), this, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
datePickerDialog.getDatePicker().setMinDate(now);
datePickerDialog.show();
}
This crash happens due to a bug in CalendarView for pre-API21, and for calendarViewMode == MODE_HOLO
for API21.
Although setMinDate
contains a correction highlighted with a comment:
public void setMinDate(long minDate) {
...
mMinDate.setTimeInMillis(minDate);
// make sure the current date is not earlier than
// the new min date since the latter is used for
// calculating the indices in the adapter thus
// avoiding out of bounds error
Calendar date = mAdapter.mSelectedDate;
if (date.before(mMinDate)) {
mAdapter.setSelectedDay(mMinDate);
}
// reinitialize the adapter since its range depends on min date
mAdapter.init();
The check in setSelectedDay
compares mMinDate
and mSelectedDate
only with date accuracy:
public void setSelectedDay(Calendar selectedDay) {
if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDate.get(Calendar.DAY_OF_YEAR)
&& selectedDay.get(Calendar.YEAR) == mSelectedDate.get(Calendar.YEAR)) {
return;
}
mSelectedDate
and mMinDate
are points into the same day, so that mSelectedDate
will remain unchanged (i.e. in a wrong state mSelectedDate < mMinDate
).
Then the control flow will run up to mAdapter.init
, and then into getWeeksSinceMinDate
. In this function a comparison of mMinDate
and mSelectedDate
will be performed with millisecond accuracy:
private int getWeeksSinceMinDate(Calendar date) {
if (date.before(mMinDate)) {
throw new IllegalArgumentException("fromDate: " + mMinDate.getTime()
+ " does not precede toDate: " + date.getTime());
}
And because mSelectedDate
was initialized in few milliseconds before mMinDate
the crash will occur.
In a newer implementation this code was rewritten, so this issue is missing for API21+.