Question

My application was working perfectly on my Android 2.2 emulator. I then decided to test on an Android 4.1 emulator. The DatePickerDialog looks a little different and for some reason when I press on "Done", the onDateSet() listener gets called twice and causes problems in my application.

I know this because the log shown below in the code is printed twice whenever I click on "Done"

mDateSetListener = new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            Log.v("onDateSet", "ENTERED");
            //rest of code...
    }};

Android 2.2 DatePicker

Working Android 2.2 DatePicker

Android 4.1 DatePicker

Not Working Android 4.1 DatePicker

Was it helpful?

Solution

Try setting a boolean to check for a double fire within the same dialog. Something similar to:

Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_YEAR, 1);
final DatePickerDialog dateDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
    boolean fired = false;
    public void onDateSet(final DatePicker view, final int year, final int monthOfYear, final int dayOfMonth) {
        Log.i("PEW PEW", "Double fire check");
        if (fired) {
            Log.i("PEW PEW", "Double fire occured. Silently-ish returning");
            return;
        } else {
            //first time fired
            fired = true;
        }
        //Normal date picking logic goes here
    }
}, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
dateDialog.show();

This double fire issue also happens with onTimeSet of a TimePickerDialog and this check also works for those.

OTHER TIPS

According to Ankur Chaudhary's brilliant answer on the similar TimePickerDialog issue, if we checked inside onDateSet if the given view isShown() or not, it will solve the whole issue with the minimal effort, with no need for extending the picker or checking for some hideous flags going around the code or even checking for the OS version, just do the following:

public void onDateSet(DatePicker view, int year, int month, int day) {
    if (view.isShown()) {
        // read the date here :)
    }
}

and of course the same can be done for onTimeSet as per Ankur's answer

I think this is related , I started testing on 4.1 today and have found some javascript events seem to fire twice. Mostly click at the moment. Weirdly if i add in an alert it 'sometimes' fires once. The behaviour is oddly inconsistent.

The javascript events only respond in this way on android 4.1. iPhone seems fine as do all previous versions of android i have tried so far (including 4.0.x).

It seems like an error with the browser or the way its handling javascript to me but thats just a guess.

To reiterate: This is a confirmed bug in Android. Two workarounds have already been suggested, saving the state in a (instance) variable or asking the Dialog if it isShown(). But isShown() seems to be unreliable (according to this answer's comments for example) and saving the state gets messy if you want to re-show the dialog.
A better solution is to save the state inside the Dialog itself:

public void onDateSet(DatePicker picker, int year, int monthOfYear, int dayOfMonth) {
    if (picker.getTag() == null) {
        picker.setTag("TAGGED");
        // Only gets called once per Dialog
    }
}

It's clean and effective.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top