I am stumped on this issue, my onBackPressed() method doesn't work when it has to. My scenario is as soon as activity starts, progress dialog shows up because I called asynctask.execute() in onCreate. When the process takes long time I want to give user a feature that he can dismiss the ongoing process(downloading data from the server) so I tried to dismiss the dialog and finish the activity when back button is pressed, but it's not working.
When I normally press back button after I have got the data, then the control seems to be flowing under onBackPressed().
Below is my code snippet:
public void onBackPressed() {
if(progressDialog != null && progressDialog.isShowing())
{
progressDialog.dismiss();
}
finish();
}
Is there any other way to give user an opportunity to cancel that anytime. Please suggest me how to make the entire process and activity terminated when the user presses back button.
For canceling the progress dialogue please set progress dialog cancel as true.
dialog.setCancelable(true);
Related
I have created one AsyncTask.
One progress dialog is created in onPreExecute().
While creating dialog itself cancel button is added to the dialog.
In which task is cancelled.
In onPostExecute(), dialog is dismissed.
Issue:
Point at which we tap on cancel button, and we have already reached in onPostExecute()
Here, we do not enter into Cancel button onclick Listener.
Where as, if it is inBackground(), then it properly enters into onClick Listener of Cancel button.
How to handle on that moment where user clicks on cancel, and user reaches into onPostExecute() and thats why not able to execute onClick listener??
you can check for a boolean variable in onPostExecute . if its true do your work else exit or return from that code. you can set boolean variable on your cancel button.
like
boolean canExecute = true;
and in PostExcute do
while(canExecute){}
and in cancel button set canExecute to false;
I think the problem is not exactly what you describe. (without the code it's not easy... please post some code)
Once you reach the onPostExecute and if the dialog isn't dismiss yet when the user click on Cancel: the cancel listener is executed, but the asyncTask.cancel(...) will fail : i.e. it return false (since the task is already executed).
If your need is to interrupt the onPostExecute code : then move that code in the AsyncTask.doInBackground and keep the code of the button cancel as simple as possible :
if(asyncTask.cancel(true)){
dialog.dismiss();
}else{
//the asyncTask is already in the onPostExecute
//the dialog will be dismissed in the onPostExecute... so don't do anything.
}
Keep the code of the onPostExecute() as simple as possible :
dialog.dismiss();
In my app I have several activities one after the other. After my login screen I have Home screen and after that several screens. Now When user select device home button or power off button I want to display login screen when user again comes to my app and then Home screen. Rest all activity I am finishing it from my base class. Now till here I have done, My problem is when I show a dialog in some other activity and at that instance if user click on home or power button, then i am getting WINDOW LEAKED EXCEPTION.
Like I have TempActivity is displaying a dialog and user clicked home button so StoreActivity and TempActivity will finish but Dialog never got chance to be dismissed. So What would be the best way to deal with this situation.
Is there some better way to dismiss the dialog so that I don't get any exception.
Override onDestroy, there, check whether the dialog is present, if so, dismiss it.
dismiss() in onDestroy() doesn't solve this problem. Try to override activity.finish() like:
#Override
public void finish() {
if(mDialog != null) {
mDialog.dismiss();
}
super.finish();
}
Put the Dialog handle in a member object, then when you finish the top activities, dismiss the dialog first.
You could make this more neat by creating abstract Activity class (which all your activities extends), which dismisses possible dialog when calling finish()
I have a timer which runs continously. When I press the BACK button I made a dialog to appear where you can quit from that intent or go back and cointinue the timer what has been stopped by the BACK button. Well if I click on the contimnue, the onResume() method makes the timer continue and it works good. But, if I press the back button when the dialog is on the screen I want the timer to go on just like if I press the Continue on the dialog. But instead, I press the back button and nothing happens, the timer is stopped and it is not good for me since some of my methods only works if the timer is going or it is stopped by the dialog. But if there is no dialog and the timer is stopped numerous potential errors can happen. So how can I stop the user to press the back button when the dialog is on the screen?
I tried something like this:
if ((keycode==back) && a=0 ) {... a=1 , onPuase()} // dialog comes in onPause() just happened
else ((keycode==back) && a=1 ) {... a=0, onResume()} //I want onResume() to happen here
But it is not good. The dialog appears on the first Back button then it disappears on the second Back (nothing happens here). The timer is still stopped here however the third back button starts the timer. So there is an unecessary Back which can cause troubles since the useres wont know that they have to press it again...
A few advices:
Do not call onResume/onPause manually, only system should make it. Else you'll have unexplainable issues on various devices.
You really want to use OnDismissListener ( http://developer.android.com/reference/android/content/DialogInterface.OnDismissListener.html ). As starting from ICS, dialog can be dismissed not only by pressing Back key, but also by tapping somewhere on screen, outside the dialog.
If you want to prevent dismissing the dialog by "back" and "tapping out of dialog" - use setCancellable(false) http://developer.android.com/reference/android/app/Dialog.html#setCancelable(boolean) for the dialog.
Good luck
If you want to be notified when user pressed BACK while your dialog was displayed, use OnDismissListener
implement OnDismissListener in your DialogClass
and override OnDismiss method
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
//you can control back button from here
}
I have code like this
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
boolean autoLogin = false;
autoLogin = checkAutoLogin();
if(autoLogin) {
showProgress();// Show progress dialog
if(login(savedUserName,savedPassword)) {
//call home activity using startActivity();
}
// login(savedUserName,savedPassword), this function access the server and return true if username and password correct- this works properly
}
}
Now the question is, i get display of home activity without displaying main activity and its progress dialog, during the authentication time of login(savedUserName,savedPassword)(this function take countable time because of server authentication) function, I got only a black screen, during this time i want show main activity and progress dialog.
Note:If i click back button in home activity i can get main activity and progress dialog
You should not do the network operation on UI thread,you can do it in separate thread and then you can call the home activity using Handler object,it iwll solve your problem
Do your Time Consuming Task in the AsynchTask. this class is designed exactly for the kind of work you are looking for.Use doInBackground() method to accomplish the task and onPreExecute you can show a progress Dialog.
Depending on what your showProgress() method contains, I'd guess that showProgress runs, sees that there is no active login attempt happening, and dismisses itself, then the login() method is called.
What you want to do is start login() asynchronously and then start the progress dialog that will check to see if login() is finished.
This is just a guess from what I can see of your code.
Could you post some more of it perhaps?
Try putting some logcat logging into the showProgress() method to see if it is in fact being created and destroyed quickly.
It was my understanding, obviously wrong, that onPause() is called whenever the back button is pressed? Now in my code I've put this onPause() event:
#Override
protected void onPause(){
super.onPause();
if(!_END_GAME){
Builder _alert = new AlertDialog.Builder(this)
.setMessage("onPause, with game NOT over!");
_alert.setNeutralButton("OK.",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
arg0.dismiss(); // Kills the interface
System.runFinalizersOnExit(true);
finish();
}
});
_alert.setTitle("Your Score!");
_alert.show();
}
}
Now the problem is, the dialog does not launch what-so-ever, and then the code errors out. I put the dialog there to try to visualize where the onPause() was called and help me debug some other variables and such. Yet like I said it never even gets shown. Any ideas why this would be? Is there a function that is launched prior to onPause() when the back button is pressed? Thank you in advance for any info.
onPause will always be called when your activity is no longer in the foreground, that's guaranteed. Maybe your _END_GAME is not false? Add a debug log output to your onPause method, you'll see that it always gets called.
I should note though that displaying a dialog during onPause is extremely bad form - the user is trying to get rid of your app (could even be because of an incoming phone call). You DO NOT want a dialog then. That goes against the Android design.
In fact, the Android OS will simply short-circuit your app if you try to do lengthy shenanigans in onDestroy or onPause. Basically, if those get called, you're supposed to disappear quietly.
If you really want to intercept the back button, you can check for the button like Ted suggested, but keep in mind that your app can go to the background in many other ways - home button, selected notification, incoming phone call, etc.
You should check for the back button by overriding onKeyDown, not testing in onPause. onPause gets called whenever your activity is no longer in the background leaves the foreground; it is not necessarily finishing. (You can check isFinishing() for that.) See here for more info on handling the back key.
onPause is getting called, and your dialog is showing, just for a tiny split-second before Android finishes your app. Put log statements in there if you want to watch what is going on.
If you want to show a dialog when the back button is pressed then the easiest way (works on Android 2.1+) is to override the onBackPressed method in your activity
#Override
public void onBackPressed() {
if (gameRunning) {
// show dialog
} else {
// exit
super.onBackPressed();
}
}