Cancelling a CountDownTimer on Physical Back Button Press in a Fragment - android

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();
}
}

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.

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();
}

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;
}
});
}

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();
}
}

have you tried onBackPressed()
#Override
public void onBackPressed() {
super.onBackPressed();
myTimer.cancel();
myTimer =null;
}

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;
}
});

Related

Back Button Does Not Stop Handler

I have an activity that runs the following:
private void loop() {
// TODO Auto-generated method stub
handler.postDelayed(new Runnable() {
public void run() {
DBListern();
handler.postDelayed(this, 5000);
}
}, 5000);
}
I would like to cancel this handle on back button:
public boolean onBackPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
handler.removeCallbacksAndMessages(null);
return true;
}
return super.onKeyDown(keyCode, event);
}
The handler is still running after back button is pressed, how can I stop it?
First of all the right name of the method you are looking for is onBackPressed(). So your code is simply not called by framework. Try
#Override
public void onBackPressed() {
handler.removeCallbacksAndMessages(null);
super.onBackPressed();
}
You need to do this way:
#Override
public void onBackPressed() {
if(mHandler!=null){
mHandler.removeCallbacks(mRunnable);
}
super.onBackPressed();
}
Reason: You need to manually remove callback of Runnable from Handler onBackPress.
Hope this would help you.
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loop();
}
private void loop() {
// TODO Auto-generated method stub
handler.postDelayed(new Runnable() {
public void run() {
Log.i(TAG,"run");
handler.postDelayed(this, 5000);
}
}, 5000);
}
Handler handler = new Handler();
#Override
public void onBackPressed() {
super.onBackPressed();
handler.removeCallbacksAndMessages(null);
}
}
this works for me.
For removed handler messeges, you need set not null in method parametrs. Its Must bee lenk on object , or message type, what do yo like to remove. And why you made this chek
if (keyCode == KeyEvent.KEYCODE_BACK) {
its realy nesesary?

Logout when the application is force closed

I want to implement the function : if user dosen't checked the autoLogin CheckBox, clear the login user information and logout when the application is quit normally or force closed(clean the memeory).
I write the code clearAutoStart() to clear user information both in finish() and OnDestory().
When the user press back button twice, the finish() will execute, and will logout success. But as you know, if the application force closed, OnDestory() will not execute all the time. So in this situation, it will not logout success.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
exitBy2Click(); //quit normal
}
return false;
}
private static Boolean isExit = false;
private void exitBy2Click() {
Timer tExit = null;
if (isExit == false) {
isExit = true;
Toast.makeText(this, "press again to quit", Toast.LENGTH_SHORT).show();
tExit = new Timer();
tExit.schedule(new TimerTask() {
#Override
public void run() {
isExit = false;
}
}, 2000);
} else {
finish();
System.exit(0);
}
}
#Override
protected void onDestroy() {
clearAutoStart();
super.onDestroy();
}
#Override
public void finish() {
clearAutoStart();
super.finish();
}
#Override
protected void onStop() {
Log.i("ws", "---->>SmarterActivity onStop");
super.onStop();
}
public void clearAutoStart() {
RememberUser rememberUser = RememberUser.getInstance();
if (rememberUser.getIsAutoStart() == false) {
Log.i("ws", "---->>clearAutoStart getIsAutoStart false ");
UserLocalStore userLocalStore = UserLocalStore.getInstance();
userLocalStore.setUserLoggedIn(false);
userLocalStore.clearUserData();
Log.i("ws", "---->>clearAutoStart getIsAutoStart false OK ");
} else {
Log.i("ws", "---->>clearAutoStart getIsAutoStart true ");
}
}
I try to add the clearAutoStart() in onStop(), but this means if I press the HOME button , the application will logout.
When you press HOME onPause() is called and then onStop().
So you can put a member variable that keep the track of what is happening:
#Override
protected void onPause() {
mIsPause = true;
super.onPause();
}
#Override
protected void onStop() {
Log.i("ws", "---->>SmarterActivity onStop");
if(!mIsPause)
clearAutoStart();
super.onStop();
}

how can I stop activity wdeviceclick back button on my device

Answered and trusted look comments !
Thank sania
public class Test extends Activity {
HTML5WebView mWebView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWebView = new HTML5WebView(this);
Intent i = getIntent();
String url = i.getStringExtra("url"); // retrieve the value you passed
if (savedInstanceState != null) {
mWebView.restoreState(savedInstanceState);
} else {
mWebView.loadUrl(url); // use that value
}
setContentView(mWebView.getLayout());
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mWebView.saveState(outState);
}
#Override
public void onStop() {
super.onStop();
mWebView.stopLoading();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
}
return super.onKeyDown(keyCode, event);
}
public void onBackPressed() {
Intent myIntent = new Intent(Test.this, fragment_main.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);// clear back stack
startActivity(myIntent);
finish();
return;
}
}
how can I stop last activity when clicked back button ? I was made a vimeo app working with listview how can I stop and close (vimeo videoplayer.class) that activity.when I click back button its going first activity or showing message Application was stopped :/
Add ondestroy () or video.stop() methods in backkey method

Disable back button for temporary time

I know this question have been asked many times around here, but i didn't find the propert answer for my issue.
this code can disable back button:
#Override
public void onBackPressed() {
// Do Here what ever you want do on back press;
}
but is there anyway that i can disable back button for a temporary time,not for the whole Activity ?
nice answer by Dixit. Just another option
public boolean onKeyDown(int keyCode, KeyEvent event) {
boolean result = false;
if (keyCode == KEYCODE_BACK) {
if (condition) {
result = true;
}
}
return result;
}
N.B ..
it will work on ancient version also
returning true from onKeyDown consumes the default behavior
You have to set on boolean flag where you have to require disable back button set flag value true;
In onBackPressed() you have to put condition as per #Dixit says
#Override
public void onBackPressed() {
if(condition to check){
// this block disable back button
}else{
// this block enable back button
super.onBackPressed();
}
}
If you want to disable backbutton for certain time use this,
//for 5 sec = 5000
countDownTimer = new CountDownTimer(5000,1000) {
#Override
public void onTick(long millisUntilFinished) {
txtWait.setTextColor(getResources().getColor(R.color.errorcolor));
txtWait.setText("Wait( " + millisUntilFinished / 1000+" sec)");
onBackPressed();
}
#Override
public void onFinish() {
YourActivityName.super.onBackPressed();
}
}.start();
And in the override method:
#Override
public void onBackPressed() {
//super.onBackPressed(); commented this to disable the back press
}
Full working code:
YourActivity extends AppCompatActivity{
boolean isBackButtonDisabled = false;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState)
setContentView(R.layout.somelayout);
disableBackButton(4000); //<--Back button is disabled
}
#Override
public void onBackPressed(){
if(!sBackButtonDisabled){
super.onBackPressed();
}
}
private void disableBackButton(final int timeInMilis){
if(!isBackButtonDisabled) {
isBackButtonDisabled = true; //<-- Keep it outside Thread code
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(timeInMilis);
} catch (InterruptedException e) {
} finally {
isBackButtonDisabled = false;
}
}
});
t.start();
}
}
}
Note: You can use disableBackButton(time) in other scenarios as well. For example Button click. If
you click button multiple times the Thread will only run once. Because in this code
isBackButtonDisable variable is thread-safe "in a way".

Disabling and enabling back button

In the app i m looking for the users location using gps.In the Async pre execute method i m showing a toast.I want that while i show that toast the back button should be disabled
aftr the location is found i want to enable the back button in the post execute!
to disable the back button i have used.But this is not working
OnKeyListener mainScreenKeyListener = new OnKeyListener() {
#Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
boolean disableEvent = false;
if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
disableEvent = true;
}
return disableEvent;
}
};
You can declare global variable disableEvent by
final boolean disableEvent;
Your Preexecute method can set it to false by
disableEvent = false;
Your Postexecute method can set it to true by
disableEvent = true;
You can override onBackPressed as shown below:
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
if (disableEvent)
{
// do nothing
}
else
{
// do something
}
}
Here you go
Assign one static variable.and set its value to "NO" in onPreExecute.
in onPostExecute assign its value to "YES".
And write following code in your onBackPressed.
#Override
public void onBackPressed() {
if (decision.equals("NO")) { //Here no means dont allow user to go back
} else {
super.onBackPressed(); // Process Back key default behavior.
}
}
hi for disable you simply call the above function
public void onBackPressed()
{
}
for enable
public void onBackPressed()
{
super.onBackPressed();
super.finish();
//Intent
}
if you want both set flag inside the function
override onBackPress method in your activity
Class A
{
public static boolean isToastShown=false;
#Override
public void onBackPressed() {
if(isToastShown==true)
return false;
else
super.onBackPressed();
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//Show your toast here
A.isToastShown=true;
new CountDownTimer(2000,2000) {
#Override
public void onTick(long millisUntilFinished) {
// TODO Auto-generated method stub
}
#Override
public void onFinish() {
A.isToastShown=false;
}
}.start();
}

Categories

Resources