19

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

Adil Soomro
  • 37,609
  • 9
  • 103
  • 153
Nouran H
  • 1,992
  • 5
  • 18
  • 24
  • 3
    same issue android 4.1 on emulator August 30th, 2012, vote here https://code.google.com/p/android/issues/detail?id=34860 – Moak Aug 30 '12 at 08:28
  • possible duplicate of [Jelly Bean DatePickerDialog --- is there a way to cancel?](http://stackoverflow.com/questions/11444238/jelly-bean-datepickerdialog-is-there-a-way-to-cancel) – Paul Lammertsma Nov 11 '13 at 09:15

4 Answers4

25

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.

Asaf Pinhassi
  • 15,177
  • 12
  • 106
  • 130
lodlock
  • 3,638
  • 1
  • 19
  • 15
  • 1
    Toggle back the `fired` variable to `false` so that the DatePicker continues to work afterwards. By the way, the problem also occurs in the TimePicker dialogs. – Siklab.ph Feb 12 '13 at 09:29
  • This work-around concept also works for the TimePicker dialogs by using a similar "fired" check upon creation. – lodlock Apr 06 '13 at 17:58
  • OMG - I have been going crazy trying to figure out why the code in the onDateSet from the datepicker wasn't working right and after some toastMEssages realized it was firing twice. Thank you sooo much - 11 hours trying to debug and it was that damn issue. THANK YOU!!!!! – gbotha May 18 '13 at 06:17
  • Happy to help out where I can. – lodlock Sep 18 '13 at 03:25
  • 3
    This is an incomplete solution. [The bug](https://code.google.com/p/android/issues/detail?id=34860#c21) is calling `onDateSet()` both upon pressing the "Done" button and when the dialog is dismissed. The latter is additionally problematic, because the date will be set when the user cancels (i.e. presses back or taps outside of the dialog). The solution posted here does not resolve this problem. – Paul Lammertsma Nov 11 '13 at 09:03
  • [This answer gives a better solution](http://stackoverflow.com/a/11493752/154306) and explains in detail what the underlying problem is. – Paul Lammertsma Nov 11 '13 at 09:14
1

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

Community
  • 1
  • 1
AbdelHady
  • 9,334
  • 8
  • 56
  • 83
0

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.

Dan
  • 87
  • 1
  • 3
  • Are there any suggestions for how to solve this error? Any workarounds?:) – Nouran H Jul 15 '12 at 14:28
  • Nothing i have found so far. Also extra to the above it only seems to be on click or touch events. not all events. (when i get some time) I will create a bug report on the android bug list. – Dan Jul 19 '12 at 17:08
0

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.

Community
  • 1
  • 1
Leon S.
  • 3,337
  • 1
  • 19
  • 16