Android Back Button and Progress Dialog

39,031

Solution 1

First, you should show your dialog from OnPreExecute, hide it in OnPostExecute, and - if necessary - modify it by publishing progress. (see here)

Now to your question: ProgressDialog.show() can take a OnCancelListener as an argument. You should provide one that calls cancel() on the progress dialog instance.

example:

    @Override
    protected void onPreExecute(){
        _progressDialog = ProgressDialog.show(
                YourActivity.this,
                "Title",
                "Message",
                true,
                true,
                new DialogInterface.OnCancelListener(){
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        YourTask.this.cancel(true);
                        finish();
                    }
                }
        );
    }

where _progressDialog is a ProgressDialog member of YourTask.

This class was deprecated in API level 26. ProgressDialog is a modal dialog, which prevents the user from interacting with the app. Instead of using this class, you should use a progress indicator like ProgressBar, which can be embedded in your app's UI. Alternatively, you can use a notification to inform the user of the task's progress. LINK

Solution 2

This can be achieved by the following code fragment:

progress.setCancelable(true);
progress.setCanceledOnTouchOutside(false);

progress is the ProgressDialog object...

This will enable the back button to close the dialog but prevent any touch input to do that...

Solution 3

Well, I had the same issue. The simplest method that worked for me is using progressDialog.setCancelable(true).. This declares whether the dialog is cancelable by hitting the back key.. Try it and let me know if it works for you or not. Good luck

Solution 4

I just found a perfect and simplest solution to this problem. There's a method in ProgressDialog to set KeyListener.

progressDialog.setOnKeyListener(new OnKeyListener() {
    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        if(keyCode==KeyEvent.KEYCODE_BACK && !event.isCanceled()) {
            if(progressDialog.isShowing()) {
                //your logic here for back button pressed event
            } 
            return true;
        }
        return false;
    }
});

It's working fine with setCancelable(false). I am also checking for event.isCanceled(), because without that I was getting two events. I've tested this on Lollipop device with and without Hardware keys.

Solution 5

Treating back button like a cancellation is not the correct way.
Cancellation also occurs when a user touches the screen outside of the dialog box. You want to differentiate those two actions, no?

Correct approach would be to extend the ProgressDialog class and override the onBackPressed method.

private class SubProgressDialog extends ProgressDialog {
    public SubProgressDialog(Context context) {
        super(context);
    }
    @Override
    public void onBackPressed() {
        /** dismiss the progress bar and clean up here **/
    }
}


public void displayProgressBar(){
    progressBar = new SubProgressDialog(this);
    progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressBar.setCancelable(false);
    progressBar.setMessage(getString(R.string.authorizing));        
    progressBar.show();   
    new Thread(new Runnable() {
      public void run() {
      }
       }).start();     

}

Notice the setCancelable(false), again emphasizing that back button is different than a simple cancellation.
Also this will effecitvely ignore any other touch inputs from the user.

Share:
39,031
jwbensley
Author by

jwbensley

Senior network engineer / architect Programmer Hobbyist hardware hacker/tinkerer

Updated on July 09, 2020

Comments

  • jwbensley
    jwbensley almost 4 years

    I have an AsyncTask that shows a progressDialog whilst working (it calls runOnUiThread from within doInBackground to show the progress dialog).

    Whilst its running I want to allow the use of the back button to cancel the operation; someone else has had this problem: BACK Button is not working ,while progressDialog is running

    For what ever reason I can't reply to that thread, hence having to start another?! (Another question for another day)

    I had the same idea as Sandy but this code is never called whilst the progressDialog is showing, why is this? I have implemented it inside my main activity class, does the progressDialog take the foreground focus away from my class temporarily?

  • jwbensley
    jwbensley about 13 years
    This is what I found. I conducted more research my self, together with your answer given, I have made it work using your suggestion :)
  • jwbensley
    jwbensley about 13 years
    Yep, this is pretty much what I was after. Managed to get it working with a interruptible progress dialogue :)
  • jwbensley
    jwbensley over 12 years
    Hi Farhan, as per user634618's suggestions I used an onCancelListener() :D
  • Asif Mujteba
    Asif Mujteba over 9 years
    No need to subclass ProgressDialog, Implement onCancelListener and use progressDialog.setCanceledOnTouchOutside(false); for getting same effect.