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+.