ess.crazy
ess.crazy

Reputation: 296

Cancel asynctask download on backbutton press

This is my download class in which I used Asynctask.Everything works fine, when the file is downloaded fully,it shows 'file downloaded' and on 'ok' press goes back to previous activity.Now I wanted to cancel the asynctask(pls not that 'cancel asynctask' and not only the 'loading' dialogue)on back button press and go back to previous activity.How to do that?someone please help.Thanks in advance

public class Download extends Activity {

public static final int DIALOG_DOWNLOAD_PROGRESS = 0;

private ProgressDialog mProgressDialog;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.down);

    startDownload();


}

private void startDownload() {
    String url = data.proj;


    new DownloadFileAsync().execute(url);
}
private void showMsg() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Document is downloaded")
           .setCancelable(false)
           .setPositiveButton("OK", new DialogInterface.OnClickListener() {
               @Override
            public void onClick(DialogInterface dialog, int id) {
                    //do things
                   Download.this.finish();
               }
           });
    AlertDialog alert = builder.create();
    alert.show();
}
@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DIALOG_DOWNLOAD_PROGRESS:
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("Downloading file..");
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setCancelable(false);

        mProgressDialog.show();


        return mProgressDialog;
    default:
        return null;
    }
}

    class DownloadFileAsync extends AsyncTask<String, String, String> {

@Override
protected void onPreExecute() {
    super.onPreExecute();
    showDialog(DIALOG_DOWNLOAD_PROGRESS);

}

@Override
protected String doInBackground(String... aurl) {
    int count;

try {

URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();

int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);

String fname;
 fname = data.proj.substring( data.proj.lastIndexOf('/')+1, data.proj.length() );

InputStream input = new BufferedInputStream(url.openStream());
String path=Environment.getExternalStorageDirectory()
        .toString() + File.separator;
OutputStream output = new FileOutputStream(path+fname);


byte data[] = new byte[1024];

long total = 0;

    while ((count = input.read(data)) != -1) {
        total += count;
        publishProgress(""+(int)((total*100)/lenghtOfFile));
        output.write(data, 0, count);
    }

    output.flush();
    output.close();
    input.close();
} catch (Exception e) {}

return null;

}
@Override
protected void onProgressUpdate(String... progress) {
     Log.d("ANDRO_ASYNC",progress[0]);
     mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}

@Override
protected void onPostExecute(String unused) {
    dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
    showMsg();
}
}}

Upvotes: 2

Views: 2729

Answers (2)

swarajk1
swarajk1

Reputation: 492

Really old question, but it seems many people still face an issue in cancelling AsyncTasks. So, here goes...

You will need a field in your AsyncTask class (DownloadFileAsync) to store the View which is being used to cancel the task (a ProgressDialog here).

For ProgressDialog, when creating the dialog, pass true to setCancelable()

mProgressDialog.setCancelable(true);

To pass the view, change the call to the Task as follows:

new DownloadFileAsync(mProgressDialog).execute(url);

and inside our AsyncTask class, create a constructor which saves this value to a field and register an OnCancelListener to call cancel method of AsyncTask:

ProgressDialog mProgressDialog;

DownloadFileAsync(ProgressDialog progressDialog) {
    mProgressDialog = progressDialog;
    mprogressDialog.setOnCancelListener(new OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            cancel(true);
        }
    });
}

In your while loop in doInBackground, add the following code inside the loop:

if (isCancelled()) {
    outputStream.flush();
    outputStream.close();
    inputStream.close();
    return null;
}

This way we are checking whether the task was cancelled, every once in a while, and if yes, we close open streams and stop running the task with return (return will be of type given for result of Task). Next, in onCancelled

@Override
protected void onCancelled (Integer fileSize) {
    super.onCancelled(fileSize);
    Log.d("TASK TAG", "Cancelled.");
    //anything else you want to do after the task was cancelled, maybe delete the incomplete download.
}

Upvotes: 3

Maulik Sheth
Maulik Sheth

Reputation: 574

this is how i did

public class downloadAllFeeds extends AsyncTask<Void, Void, Void> 
implements OnCancelListener{


    protected void onPreExecute() {
    pDialog2.setCancelable(true);
    pDialog2.setOnCancelListener(this);
    }

    @Override
    public void onCancel(DialogInterface dialog) {
    // TODO Auto-generated method stub
    downloadAllFeeds.this.cancel(true);
    Log.d("on click cancel true","true");
    }

    @Override
    protected Void doInBackground(Void... params) {
    if(isCancelled()==true){
    //cancel true stop async
    Log.d("cancel true","true");

    }else{
      //perform your task
     }
}

this worked for me, i know this is very old question but it didnt have a answer so i thought i should share what i just now could implement :)

Upvotes: 0

Related Questions