Search code examples
androidtimepickerandroid-4.2-jelly-bean

TimePickerDialog and Jelly Bean, onTimeSet fires on cancel


If I use the TimePickerDialog in Jelly Bean, the dialog doesn't have a cancel button, and no matter what I do (like try the back button), the onTimeSet will always fire, so I have no way of knowing if the user didn't want to take action or not.

I've tried adding onCancel and onDismiss handlers, but the cancel is called after the onTimeSet handler.

On ICS, GB, there's a cancel button that works just fine.

Create default application, add Button to layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show Me" >
    </Button>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world"
        tools:context=".MainActivity" />

</RelativeLayout>

And then have the following in the main code:

package com.example.example;

import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TimePicker;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.Button01);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Dialog d = new TimePickerDialog(MainActivity.this, new TimePickerDialog.OnTimeSetListener() {
                    @Override
                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                        Log.i("Hello", "onTimeSet called");
                    }
                }, 8, 0, false);
                d.setCancelable(true);
                d.setOnCancelListener(new TimePickerDialog.OnCancelListener() {

                    @Override
                    public void onCancel(DialogInterface dialog) {
                        Log.i("Hello", "onCancel called");

                    }
                });

                d.setOnDismissListener(new TimePickerDialog.OnDismissListener() {

                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        Log.i("Hello", "onDismiss called"); 
                    }
                });

                d.show();
            }
        });   
    }
}

Solution

  • OK, it looks like there's the similar bug for DatePicker here, but I had to modify my code by casting the Dialog to an AlertDialog before calling setButton()

    ((AlertDialog) d).setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // Turn on your cancel flag here
                    }
                });