How do I stop my AsyncTask? - android

My asynctask downloads a file in background when the app is opened, once the file gets downloaded, it starts an activity. Which is working fine. The problem is, I want to STOP my asynctask from downloading and opening activity if I close the app. I have tried this, It stops the service, but the AsyncTask doesn't stop.
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#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);
InputStream input = new BufferedInputStream(url.openStream());
// OutputStream output = new
// FileOutputStream("/sdcard/.temp");//.temp is the image file
// name
OutputStream output = new FileOutputStream(VersionFile);
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;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC", progress[0]);
}
#Override
protected void onPostExecute(String unused) {
//start activity
Intent dialogIntent = new Intent(context,
NSOMUHBroadcastDisplay.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
// now stop the service
context.stopService(new Intent(context,
NSOMUHBroadcastService.class));
}
}
#Override
public void onDestroy() {
Log.v("SERVICE", "Service killed");
stopService(new Intent(this, NSOMUHBroadcastService.class));
super.onDestroy();
}

First of all you need a reference to your AsyncTask instance. Let's say
DownloadFileAsync mTask;
You need to call:
mTask.cancel(true);
This is still not enough. Inside your doInBackground() method, you have to check if the AsyncTask has been cancelled.
if(isCancelled) {
// exit
}
In your case probably you can use this check inside your while, so that if the Task is cancelled you close the stream and finish.
NOTE: In case you don't care about stopping the work in the doInBackground(), calling mTask.cancel(true) is enough, because the isCancelled() method is automatically called in the onPostExecute().

use yourtask.cancel() in onDestroy().
Use this link for more clarification: Android - Cancel AsyncTask Forcefully

Related

How do I disconnect this AsyncTask?

How can I close this connection and Asynctask if url doesn't exist. Please kindly help me .
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadFile().execute("https://i.stack.imgur.com/w4kCo.jpg");
}
Download task is below and I can't control it to be stopped, progress is started and still showing if url is invalid.
class DownloadFile extends AsyncTask<String,Integer,Long> {
ProgressDialog mProgressDialog = new ProgressDialog(MainActivity.this);// Change Mainactivity.this with your activity name.
String strFolderName;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.setMessage("Downloading Image ...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setCancelable(false);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.show();
}
#Override
protected Long doInBackground(String... aurl) {
int count;
try {
URL url = new URL((String) aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
String targetFileName="downloadedimage.jpg";//Change name and subname
int lenghtOfFile = conexion.getContentLength();
String PATH = Environment.getExternalStorageDirectory()+"/myImage/";
File folder = new File(PATH);
if(!folder.exists()){
folder.mkdir();//If there is no folder it will be created.
}
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(PATH+targetFileName);
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;
}
protected void onProgressUpdate(Integer... progress) {
mProgressDialog.setProgress(progress[0]);
if(mProgressDialog.getProgress()==mProgressDialog.getMax()){
mProgressDialog.dismiss();
Toast.makeText(getApplicationContext(), "Download Completed !", Toast.LENGTH_LONG).show();
}
}
protected void onPostExecute(String result) {
}
}
All required permissions added properly.
You can call cancel() on the AsyncTask. Any calls to isCancelled() after that will return true. This doesn't necessarily mean your doInBackground method will stop executing. You have to manually check isCancelled() during that method to exit gracefully. Although once you call cancel(), onPostExecute() will not get called. onCancelled() will get called however.
Change this line in your code
class DownloadFile extends AsyncTask<String,Integer,Boolean> {
protected Boolean doInBackground(String... aurl) {
Now when you url fails on doInBackground method just return false from there
Now you can check this on
#Override
protected void onPostExecute(Boolean result) {
if(!result){
mProgressDialog.dismiss();
}
super.onPostExecute(aLong);
}

AsyncTask How to get progress from MainActivity [duplicate]

This question already has answers here:
Download a file with Android, and showing the progress in a ProgressDialog
(16 answers)
Closed 8 years ago.
Hello i am writing a download project and i'm stuck right here.
#Override
protected void onProgressUpdate(Integer... progress) {
}
//I'm using in my mainactivity like that
Download download = new Download();
download.execute("http://");
I want to get progress when updated and yeah i can do this using onProgressUpdate but i wonder about can i get it from my mainactivity i mean where i called the class. I love that kinda dynamic classes because i can use them easily my every project. Thank you btw forgive me for my grammar.
I can see two options here :
You either pass the object where you want to display the progress to your AsyncTask with the constructor and then you store it :
private ProgressObject mObject;
public void MyAsyncTask(ProgressObject object) {
mObject = object
}
And the update in the onProgress() method :
object.setProgress(); //assuming the ProgressObject has a method setProgress() obviously
Or you can set up some kind of listener :
public interface ProgressListener() {
public void onProgress(int progress);
}
private mProgressListener;
public void MyAsyncTask(ProgressListener listener) {
mProgressListener = listener;
}
then use it in the onProgress() method :
mProgressListener.onProgress(80);
Just some examples, not much but I hope that help.
Use this
class DownloadFileAsync extends AsyncTask<String, String, String> {
#SuppressWarnings("deprecation")
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
File root = android.os.Environment.getExternalStorageDirectory();
//
File dir = new File (root.getAbsolutePath()+"/downoad"); //make ur folder to put download
if(dir.exists()==false) {
dir.mkdirs();
}
File file = new File(dir, "enter file name");
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);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(file);
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;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#SuppressWarnings("deprecation")
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
Toast.makeText(DisplayActivity.this,"Successfully downloaded in phone memory.", Toast.LENGTH_SHORT).show();
}
}
How to call?
new DownloadFileAsync().execute("your URL");

ProgressBar is not updating from AsyncTask

I'm using ProgressBar to try and display the progress of downloading and saving a file. The ProgressBar shows up, but stays at 0, until it closes when the task is finished. I've tried different approaches, but it just won't update. Is there something wrong with the code?
class downloadData extends AsyncTask<Void, Integer, Void>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params)
{
int count;
try
{
URL url = new URL("http://google.com");
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream is = url.openStream();
File testDirectory = new File(MainActivity.this.getFilesDir(), "downloadedData.txt");
if (!testDirectory.exists())
{
testDirectory.mkdir();
}
FileOutputStream fos = new FileOutputStream(testDirectory+"/downloadedData.txt");
byte data[] = new byte[1024];
long total = 0;
while ((count = is.read(data)) != -1)
{
total += count;
int neki = (int)(((double)total/lenghtOfFile)*100);
this.publishProgress(neki);
fos.write(data, 0, count);
}
is.close();
fos.close();
}
catch (Exception e)
{
Log.e("ERROR DOWNLOADING","Unable to download" + e.getMessage());
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values)
{
super.publishProgress(values);
progressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
progressDialog.dismiss();
}
}
onCreate
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(true);
progressDialog.setMax(100);
progressDialog.setMessage("Downloading Data");
And when the button is clicked that starts the downloading: progressDialog.show();
Try to debug where the progress is calculated. It might be a cast problem, you can try to do it in 2 steps to avoid getting 0 after your division. But again you should create a variable with this progress value, put a breakpoint there and see the casting problem !
I am not sure what the problem might be in your code, but you have have a go at this progressDialog.incrementProgressBy(incrementValue);
This may sound a bit tard but have you tried to invalidate() the ProgressBar after you set the progress? I am not sure it does one automatically when you set the progress.
I was also facing the same problem and spent hours on it. The problem is in calculation of the progress value.
int neki = (int)(((double)total/lenghtOfFile)*100);
Instead you should do calculation in two steps:
int neki = total * 100;
neki = (int)(neki/lengthOfFile);
publishProgress(neki);
This solved my problem. Hope this will help.

android 2.1 AsyncTask file download not working for multiple thread work fine when call single instance

i am using android 2.1 ,api level 7 and try to implement asynchronous file download from LAN server
for this i am trying to implement AsyncTask .When i am trying to call a single thread it works find but when call multiple its just stop both the thread
/* AsyncTask class*/
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
Log.i("count","in");
URLConnection conexion = url.openConnection();
Log.i("count","in1");
conexion.connect();
Log.i("count","in2");
File root = android.os.Environment.getExternalStorageDirectory();
Log.i("count","in3");
int lenghtOfFile = conexion.getContentLength();
Log.i("count","in4");
BufferedInputStream input = new BufferedInputStream(url.openStream());
Log.i("count","in5");
OutputStream output = new FileOutputStream(root.getAbsolutePath() + "/video" +aurl[1] +".mp4");
byte data[] = new byte[1024];
long total = 0;
Log.i("count","in6");
while ((count = input.read(data)) != -1) {
//Log.i("count","in7");
total += count;
Log.i("count",aurl[1]);
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.i("progress",progress[0]);
}
#Override
protected void onPostExecute(String unused) {
Log.i("process","end");
}
}
/*main method call*/
private void startDownload() {
Log.v("count","out");
String url = lanurl+"titanic/video"+1+"_en.m4v";
new DownloadFileAsync().execute(url,"1");
url = lanurl+"titanic/video"+2+"_en.m4v";
new DownloadFileAsync().execute(url,"2");
}
output :
download both file in sd card
but no file downloading properly
I didn't understand the complete Question. But seems like your problem is with AsyncTask.
Single Object created for an AsyncTask can be used only once. If you want to use it again, you need to create an another object for the same AsyncTask.

How to get back the task completion status in AsyncTask

This is related to my previous post Problem with downloading multiple files using AsyncTask
I'm trying to download two video files and also show a ProgressDialog during the process. For this I'm using AsyncTask. I want the 1st download to complete, free up memory then start the 2nd download. I wrote the following code to achieve this, but it seems the 2nd download never begins.
startDownload() {
DownloadFileAsync d1 = new DownloadFileAsync();
d1.execute(videoPath+fileNames[0],fileNames[0]);
if(d1.getStatus()==AsyncTask.Status.FINISHED) {
d1 = null;
DownloadFileAsync d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
}
Is there a way that I can get back the completion status of my 1st task & then start the 2nd ?
The following is the code of my DownloadFileAsync class:
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();
File root = android.os.Environment.getExternalStorageDirectory();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(root.getAbsolutePath() + "/videos/" + aurl[1]);
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;
}
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);
tv.append("\n\nFile Download Completed!");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
}
}
As DKIT Android suggested, you could start the second download from onPostExecute, but only if for example download2 is null
#Override
protected void onPostExecute(String unused)
{
if (d2 == null)
{
d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
}
If you need to start more downloads, just write the method outside of your asynctask, which will check which download should be started next.
Start your second download from within your first onPostExecute-method.
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
tv.append("\n\nFile Download Completed!");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
// Here you start your new AsyncTask...
}
This code:
if(d1.getStatus()==AsyncTask.Status.FINISHED) {
d1 = null;
DownloadFileAsync d2 = new DownloadFileAsync();
d2.execute(videoPath+fileNames[1],fileNames[1]);
}
...will execute once, and immediately after the first AsyncTask is executed, thus it will always be false. If you want to go that route, you need to do it in a while loop - which kind of defeats the point of making the task Async in the first place.

Categories

Resources