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.
Related
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
I have a program with one button click, when clicked, 4 Downloads should executed Simultaneously. I use ASyncTask class for this purpose with for iterator:
for(int i=0;i<downloadCounts;i++){
new DownloadTask().execute(url[i]);
}
but in running, only one download executed and all 4 progressbars show that single download.
I want to download 4 downloads in same time. how can I do?
for more details, my download manager, get a link and divide it to 4 chunks according to file size. then with above for iterator , command it to run 4 parts download with this class:
private class DownloadChunks extends AsyncTask<Long,String,String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
setStatusText(-1);
}
#Override
protected String doInBackground(Long... params) {
long s1 = params[0];
long s2 = params[1];
int count;
try{
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Range", "bytes=" + s1 + "-" + s2);
connection.connect();
len2 = connection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream(),8192);
File file = new File(Environment.getExternalStorageDirectory()+"/nuhexxxx");
if(!file.exists())file.mkdirs();
OutputStream output = new FileOutputStream(file+"/nuhe1.mp3");
byte[] data = new byte[1024];
long total = 0;
while ((count= input.read(data))!=-1){
total += count;
publishProgress(""+(int)((total*100)/len2));
output.write(data,0,count);
}
output.flush();
output.close();
input.close();
counter++;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
setStatusText(Integer.parseInt(values[0]));
}
#Override
protected void onPostExecute(String aVoid) {
super.onPostExecute(aVoid);
Log.e("This part is downloaded", "..." + len2 + " start with: " + counter);
}
}
All logs shows that every thing is OK and file is completely downloaded. but each chunk download separate and in order. I want to download chunks Simultaneously
Instead of just call the .execute() method of your AsyncTask, use this logic to achieve what you want:
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
} else {
new MyAsyncTask().execute(params);
}
Check more info from the official documentation of AsyncTask
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");
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.
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.