'Android Dialog with CountDown TImer

In my app, I show the push notification as a Dialog that has two buttons named Yes and No. I need to show a timer (20 seconds) running in the dialog's title.

If the user clicks Yes, it should go to an activity.
If the user clicks No, the dialog gets canceled before timer ends.
When the countdown finishes,the Dialog should disappear. How should I implement this?

Here is my Alert dialog Method

public void showAlertDialog(final Context context, String title, String message,
                            Boolean status) {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);

    // Setting Dialog Title
    alertDialog.setTitle(title);

    // Setting Dialog Message
    alertDialog.setMessage(message);

    // Setting Icon to Dialog
    //alertDialog.setIcon(R.drawable.fail);

    // Setting Positive "Yes" Button
    alertDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            Toast.makeText(getApplicationContext(), "You clicked on YES", Toast.LENGTH_SHORT).show();

        }
    });

    // Setting Negative "NO" Button
    alertDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            Toast.makeText(getApplicationContext(), "You clicked on NO", Toast.LENGTH_SHORT).show();

            dialog.cancel();
        }
    });

    // Showing Alert Message
    //alertDialog.setIcon(R.drawable.counter);
    alertDialog.show();
}


Solution 1:[1]

I wouldn't recommend adding the countdown into the dialog's title. If you instead add it to the No button, it is more obvious for the user what will happen when the countdown finishes.

Here's code for an AlertDialog that does just that.

AlertDialog dialog = new AlertDialog.Builder(this)
        .setTitle("Notification Title")
        .setMessage("Do you really want to delete the file?")
        .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO: Add positive button action code here
            }
        })
        .setNegativeButton(android.R.string.no, null)
        .create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
    private static final int AUTO_DISMISS_MILLIS = 6000;
    @Override
    public void onShow(final DialogInterface dialog) {
        final Button defaultButton = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_NEGATIVE);
        final CharSequence negativeButtonText = defaultButton.getText();
        new CountDownTimer(AUTO_DISMISS_MILLIS, 100) {
            @Override
            public void onTick(long millisUntilFinished) {
                defaultButton.setText(String.format(
                        Locale.getDefault(), "%s (%d)",
                        negativeButtonText,
                        TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) + 1 //add one so it never displays zero
                ));
            }
            @Override
            public void onFinish() {
                if (((AlertDialog) dialog).isShowing()) {
                    dialog.dismiss();
                }
            }
        }.start();
    }
});
dialog.show();

dialog with countdown screenshot

Solution 2:[2]

To answer this question I have prepared a simple project at Github:

screenshot

Here is my custom dialog class, which posts a runnable at the main thread handler and updates the text label on the "Cancel" button (the negative button) every second, until zero is reached:

public class MyDialog extends AppCompatDialogFragment {
    public final static String TAG = MyDialog.class.getName();
    private long mCountDown = 20L;
    private final Handler mHandler = new Handler();
    private final Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            AlertDialog dialog = (AlertDialog) requireDialog();
            Button negativeButton = dialog.getButton(AlertDialog.BUTTON_NEGATIVE);
            negativeButton.setText(getString(R.string.dialog_cancel_button, mCountDown));
            if (--mCountDown <= 0) {
                dismiss();
            } else {
                mHandler.postDelayed(this, 1000L);
            }
        }
    };

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(requireActivity())
            .setTitle(R.string.dialog_title)
            .setPositiveButton(R.string.dialog_ok_button, (dialogInterface, i) -> Log.d(TAG, "Ok clicked"))
            .setNegativeButton(getString(R.string.dialog_cancel_button, mCountDown), null)
                .create();
    }

    @Override
    public void onStart() {
        super.onStart();
        mRunnable.run();
    }

    @Override
    public void onStop() {
        super.onStop();
        mHandler.removeCallbacks(mRunnable);
    }
}

As you see the class is quite simple. To launch the dialog just run:

MyDialog dialog = new MyDialog();
dialog.show(getSupportFragmentManager(), MyDialog.TAG);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 kiranking
Solution 2