Android: Android 4.1 Emulator Invoking onDateSet Twice from DatePicker Dialog
Asked Answered
F

4

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

Flavoprotein answered 8/7, 2012 at 13:41 Comment(2)
same issue android 4.1 on emulator August 30th, 2012, vote here code.google.com/p/android/issues/detail?id=34860Creamer
possible duplicate of Jelly Bean DatePickerDialog --- is there a way to cancel?Finback
M
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.

Mercurous answered 31/7, 2012 at 20:12 Comment(6)
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.Mcleod
This work-around concept also works for the TimePicker dialogs by using a similar "fired" check upon creation.Mercurous
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!!!!!Silvertongued
Happy to help out where I can.Mercurous
This is an incomplete solution. The bug 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.Finback
This answer gives a better solution and explains in detail what the underlying problem is.Finback
S
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

Salpa answered 16/3, 2015 at 17:35 Comment(0)
S
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.

Sarcoma answered 13/7, 2012 at 11:43 Comment(2)
Are there any suggestions for how to solve this error? Any workarounds?:)Flavoprotein
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.Sarcoma
Y
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.

Youngling answered 29/4, 2015 at 13:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.