Fawzan
Fawzan

Reputation: 4849

Cancelling a CountDownTimer on Physical Back Button Press in a Fragment

I am using a CountDownTimer in a Fragment and trying to stop it if the user hit the physical back button in the phone. I have tried overriding onPause, onDestroy, onStop, onDestroyView but nothing seems to be working. Kind of lost here. Can some one give me a pointer here?

public class Foo extends Fragment {

    CountDownTimer myTimer;

    @Override
    public void onStop() {
        super.onStop();
        myTimer.cancel();
    }

    @Override
    public void onPause() {
        super.onPause();
        myTimer.cancel();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        myTimer.cancel();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        myTimer.cancel();
    }

    @OnClick(R.id.btn_greenleft_no)
    public void goBack() {

        myTimer.cancel();
        Objects.requireNonNull(getActivity()).onBackPressed();
    }

    @OnClick(R.id.btn_greenright_yes)
    public void showSuccess(View view) {

        markAll();
        myTimer.cancel();
        (new MusicPlayer()).playSound(getContext(), "cheers.mp3");

        final Snackbar snackbar = Snackbar.make(snackBarView, R.string.congratulations, Snackbar.LENGTH_SHORT);

        snackbar.show();
        myTimer.cancel();


    }


    private void startTimer(final View view) {

        int Seconds = 5;

        myTimer = new CountDownTimer(Seconds * 1000 + 1000, 1000) {

            public void onTick(long millisUntilFinished) {

                String rem = String.valueOf(millisUntilFinished / 1000);
                    Log.d("APP_DEBUG", "Timer: " + rem);

            }

            public void onFinish() {
                goBack();
                }
        }.start();

    }

}

Upvotes: 9

Views: 1855

Answers (6)

Amit Jangid
Amit Jangid

Reputation: 2889

You have to call countDownTime.finish() as well. I have used it and it works for me.

@Override
public void onDetach()
{
    super.onDetach();

    if (countDownTimer != null)
    {
        countDownTimer.cancel();
        countDownTimer.onFinish();
    }
}

Upvotes: 3

BMU
BMU

Reputation: 429

Have you tried adding an OnKeyListener in your fragment like this: Here "view" is the parent layout of your fragment , the one that hosts the timer.

view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            Log.i(tag, "keyCode: " + keyCode);
            if( keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
               myTimer.cancel();
                return true;
            } 
            return false;
        }
    });

Upvotes: 0

hossam scott
hossam scott

Reputation: 478

For fragment you cant use onBackPressed method, Instead please use this code

 @Override
public void onResume() {
    super.onResume();
    if (getView() == null) {
        return;
    }
    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                myTimer.cancel();
                return false;
            }
            return true;
        }
    });
}

Upvotes: 3

deadfish
deadfish

Reputation: 12304

Try to modify onBackPressed in Your fragment's parent activity.

@Override
public void onBackPressed() {

    // I assume this is the way how You add fragment to fragment manager
    //getSupportFragmentManager().beginTransaction().replace(android.R.id.content, Foo.getInstance(), Foo.TAG).commit()

    // Find fragment by its string TAG and when You get it, call to stop countDownTimer
    Foo foo = (Foo) getSupportFragmentManager().findFragmentByTag(Foo.TAG);
    if (foo != null) {
        foo.stopCountDownTimer();
    }

    super.onBackPressed();
}

Next step is to declare in Your Foo fragment two things:

public static final String TAG = "Foo";

and

public void stopCountDownTimer() {
    myTimer.cancel();
}

Upvotes: 3

Shobhit Puri
Shobhit Puri

Reputation: 26017

Here is my 2 cents. Fragment doesn't have an onBackPressed() method which is present in the Activity class. It gets called when physical back button is pressed by the user. Here is what docs says:

Called when the activity has detected the user's press of the back key. The default implementation simply finishes the current activity, but you can override this to do whatever you want.

What you can do is override the onBackPressed() method in the parent activity of your Foo fragment, then using an interface communicate to the fragment that back button was pressed by the user. Inside the fragment you can have the desired code to cancel the timer. This answer in the question How to implement onBackPressed() in Fragments? can help with sample code.

Upvotes: 7

Kevin Kurien
Kevin Kurien

Reputation: 842

have you tried onBackPressed()

 @Override
    public void onBackPressed() {
            super.onBackPressed();
            myTimer.cancel();
            myTimer =null;
    }

Upvotes: 0

Related Questions