Hi I need to show summary progress of AsyncTask. I want to show ProgressBar or ProgressDialog of Downloading, but I have know idea what to do, I know how to show dialog, but only when I download one file, and how do when I have a lot of files to download. Can somebody help????
Here is My AyncTaskClass
public class DownloadProgramTask extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
String path = sUrl[1];
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
// download the file
input = connection.getInputStream();
output = new FileOutputStream(path);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
// allow canceling with back button
if (isCancelled()) {
input.close();
return null;
}
total += count;
// publishing the progress....
if (fileLength > 0) // only if total length is known
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
}
And I create new instance of that class for every execute,
File voiceFile = new File(dirVoice, a.getPose_id() + ".mp3");
if (!voiceFile.exists()) {
voiceList.add(a.getVoice());
new DownloadProgramTask().execute(MYurl.BASE_URL + a.getVoice(), voiceFile.getPath());
Log.e("LINK", MYurl.BASE_URL + a.getVoice());
Log.e("Path voice", "" + voiceFile.getPath());
}
File imgLargeFile = new File(dirImageLarge, a.getId() + ".png");
if (!imgLargeFile.exists()) {
imgLargeList.add(a.getVoice());
new DownloadProgramTask().execute(MYurl.BASE_URL + "/" + a.getImgLarge(), imgLargeFile.getPath());
}
you can use the overridden method OnProgressUpdate of Async Task. call publishProgress in doingBackground of asynctask with interger
something like this..
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.i("makemachine", "onProgressUpdate(): " +
percentBar.setProgress((values[0] * 2) + "%");
}
Related
What I want to do now is loop download pdf from URL that has about 875 Files.
I have already done this by using Asynctask and update the progress in progress dialog also everything is working fine, but what I had a problem is when the user clicks on my DOWNLOAD IN BACKGROUND button, the download is still going on and then I want to re-open the activity again. but the progress and name of the file that displays to the user is not showing anymore.
I know that when we start new activity it will ignore the background running process of our last Asynctask, so how could we solve this problem? (sorry for my English, it's my first time through on StackOverflow)
my code is similar to this
Here sample of my code:
class DownloadFileFromURL extends AsyncTask<ArrayList<LawDocument>,Integer, String> {
private boolean running = true;
Exception error;
#Override
protected void onPreExecute() {
super.onPreExecute();
if(haveNetworkConnection()){
showDialog(progress_bar_type);
}else {
running = false;
showdailog();
}
}
#Override
protected void onCancelled() {
super.onCancelled();
running = false;
}
#Override
protected String doInBackground(ArrayList<LawDocument>[] f_url) {
ArrayList<LawDocument> passed = f_url[0]; //get passed arraylist
System.out.println("Data::" + passed.size());
int count;
InputStream input = null;
OutputStream output = null;
while(!isCancelled()) {
try {
for (int i = 0; i < passed.size(); i++) {
File file = getBaseContext().getFileStreamPath(passed.get(i).getActualFilename());
if (file.exists()){
countfile+=1;
pDialog.setMessage(" Exist / "+ConstantClass.filecount);
}else{
Log.d("checkFilecount" + i, "fileName: " + passed.get(i).getFileName());
String filename = passed.get(i).getFileName().substring(passed.get(i).getFileName().lastIndexOf("/") + 1);
Log.d("checkFile", "name: " + filename);
URL url = new URL(passed.get(i).getFileName());
System.out.println("Data::" + passed.get(i).getFileName());
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
input = new BufferedInputStream(url.openStream(), 8192);
//input = new BufferedInputStream(url.openStream(), 20000);
System.out.println("Data::" + passed.get(i).getFileName());
System.out.println("Data::" + filename);
// Output stream to write file
output = new FileOutputStream(getApplicationContext().getFilesDir() + "/" + filename);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress((int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
countfile+=1;
runOnUiThread(new Runnable() {
#Override
public void run() {
pDialog.setMessage(countfile+" / "+ConstantClass.filecount);
}
});
}
}
} catch (Throwable t) {
Log.e("AsyncTask", "OMGCrash", t);
// maybe throw it again
Toast.makeText(DownloadLoading.this,"There is a problem",Toast.LENGTH_SHORT).show();
throw new RuntimeException(t);
} finally {
if (output != null) {
try {
output.flush();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return null;
}
/**
* Updating progress bar
*/
protected void onProgressUpdate(Integer... progress) {
// setting progress percentage
pDialog.setProgress(progress[0]);
}
/**
* After completing background task Dismiss the progress dialog
**/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
//dismissDialog(progress_bar_type);
if (error !=null){
Toast.makeText(DownloadLoading.this, error.getMessage(),
Toast.LENGTH_SHORT).show();
}else if(!running){
Log.d("Faild","Download fail connection");
}else{
Toast.makeText(DownloadLoading.this, "Success", Toast.LENGTH_SHORT).show();
}
}
}
}
}
I guess the Best solution to you is using Service with BroadCast
which Mean but all your download In Service
lets say
public class DowloadService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle extras = intent.getExtras();
your_data = extras.get() // just example
for (int i = 0; i < passed.size(); i++) {
File file = getBaseContext().getFileStreamPath(passed.get(i).getActualFilename());
if (file.exists()){
countfile+=1;
pDialog.setMessage(" Exist / "+ConstantClass.filecount);
}else{
Log.d("checkFilecount" + i, "fileName: " + passed.get(i).getFileName());
String filename = passed.get(i).getFileName().substring(passed.get(i).getFileName().lastIndexOf("/") + 1);
Log.d("checkFile", "name: " + filename);
URL url = new URL(passed.get(i).getFileName());
System.out.println("Data::" + passed.get(i).getFileName());
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
input = new BufferedInputStream(url.openStream(), 8192);
//input = new BufferedInputStream(url.openStream(), 20000);
System.out.println("Data::" + passed.get(i).getFileName());
System.out.println("Data::" + filename);
// Output stream to write file
output = new FileOutputStream(getApplicationContext().getFilesDir() + "/" + filename);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress((int) ((total * 100) / lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
countfile+=1;
// send broadcast with data you want
ntent.putExtra("dataType",dataType);
intent.putExtra("getAccuracy",gpsSignal);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
});
return START_NOT_STICKY;
}
}
and then in your activiy Setup Local BroadCast To get Data send
private class BroadCastLocal extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
if (Constrains.PEDOMETERBROADCAST.equalsIgnoreCase(intent.getAction()))
{
int dataType = intent.getIntExtra("dataType",-1);
}
}
Now whenever the user start/end your activity .. the process will not be effected
I want to download an image via AsyncTask and want to display it in an ImageView I am able to do it normally but I also want to show the progress to the user and do all this without having to store the file in the SDcard.
Here is what I have done so far.
class DownloadFileFromURL extends AsyncTask<String, String, String> {
/**
* Before starting background thread
* Show Progress Bar Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(progress_bar_type);
}
/**
* Downloading file in background thread
* */
#Override
protected String doInBackground(String... f_url) {
int count;
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream("/sdcard/downloadedfile.jpg");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress(""+(int)((total*100)/lenghtOfFile));
// writing data to file
output.write(data, 0, count);
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
/**
* Updating progress bar
* */
protected void onProgressUpdate(String... progress) {
// setting progress percentage
pDialog.setProgress(Integer.parseInt(progress[0]));
}
/**
* After completing background task
* Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String file_url) {
// dismiss the dialog after the file was downloaded
dismissDialog(progress_bar_type);
// Displaying downloaded image into image view
// Reading image path from sdcard
String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.jpg";
// setting downloaded into image view
my_image.setImageDrawable(Drawable.createFromPath(imagePath));
}
}
If you don't want to download image locally, you should use ByteArrayOutputStream instead of FileOutputStream.
And this is the key code:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
outputStream.write(data, 0, count);
}
//after downloading the image
byte[] imageData = outputStream.toByteArray();
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
my_image.setImageBitmap(bitmap);
I didn't test it, but I believe this can help you.
You can use Glide instead:
Glide.with(this).load("http://server.com/image.jpg").into(imageView);
reference Best method to download image from url in Android
private Bitmap downloadBitmap(String url) {
HttpURLConnection urlConnection = null;
try {
URL uri = new URL(url);
urlConnection = (HttpURLConnection) uri.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode != HttpStatus.SC_OK) {
return null;
}
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
} catch (Exception e) {
Log.d("URLCONNECTIONERROR", e.toString());
if (urlConnection != null) {
urlConnection.disconnect();
}
Log.w("ImageDownloader", "Error downloading image from " + url);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
I have a strange issue in downloading files in my android application all the files without space can be downloaded but when I have a space in my filename the file will not be downloaded for example:
Will not be download but this link:
http:..../DIV/Bon de Commande.pdf
will be downloaded:
http:..../DIV/POLITIQUE_QUALITE_V6.doc
This how I download file:
protected String downloadfile(String... sUrl) {
InputStream input = null;
OutputStream output = null;
HttpURLConnection connection = null;
try {
URL url = new URL(sUrl[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
// expect HTTP 200 OK, so we don't mistakenly save error report
// instead of the file
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return "Server returned HTTP " + connection.getResponseCode()
+ " " + connection.getResponseMessage();
}
// this will be useful to display download percentage
// might be -1: server did not report the length
int fileLength = connection.getContentLength();
SharedPreferences myPreference= PreferenceManager.getDefaultSharedPreferences(getContext());
String path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/Document" ;
String Fichename=sUrl[0].replace(myPreference.getString("lientelecharge", ""), "");
String filePath=path+"/"+Fichename;
File file = new File(filePath);
if(file.exists()) {
}else{
// download the file
input = connection.getInputStream();
File folder = new File(path);
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
output = new FileOutputStream(path+"/"+Fichename);
byte data[] = new byte[4096];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
if (fileLength > 0) // only if total length is known
output.write(data, 0, count);
}
}
} catch (Exception e) {
return e.toString();
} finally {
try {
if (output != null)
output.close();
if (input != null)
input.close();
} catch (IOException ignored) {
}
if (connection != null)
connection.disconnect();
}
return null;
}
Any help would be appreciated
Petrus is right - you have to urlencode string like:
String addressToGo = URLEncoder.encode("www.123.com/55 U.doc", "utf-8");
More ways to encode the string can be found at (my favourite one is without extra libraries): URL encoding in Android
I am creating an app for my client, one of his requirements is to download and install an external apk (size approx. 62mb) on the device. The devices will be rooted, so that's not a problem. But, while downloading the apk using AsyncTask, the progress bar resets to 0% after reaching 34% (exact 34% every time, even on different devices) and throws java.io.IOException: unexpected end of stream.
Here is the code I'm using :
public class InstallAPK extends AsyncTask<Void,Integer,Void> {
ProgressDialog progressDialog;
int status = 0;
private Context context;
public InstallAPK(Context context, ProgressDialog progress){
this.context = context;
this.progressDialog = progress;
}
public void onPreExecute() {
if(progressDialog!=null)
progressDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
try {
URL url = new URL(context.getString(R.string.kodi_apk_link));
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
// getting file length
int lenghtOfFile = c.getContentLength();
Log.e("File length", ""+lenghtOfFile);
File outputFile = new File(context.getFilesDir(), context.getString(R.string.kodi_apk_name));
if(outputFile.exists()){
if(outputFile.length() != lenghtOfFile)
outputFile.delete();
else {
publishProgress(-1);
final String libs = "LD_LIBRARY_PATH=/vendor/lib:/system/lib ";
final String commands = libs + "pm install -r " + context.getFilesDir().getAbsolutePath() + "/"
+ context.getString(R.string.kodi_apk_name);
installApk(commands);
return null;
}
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
//i tried both, with and without buffered reader
BufferedInputStream bufferedInputStream = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len1 = 0, total=0;
if (lenghtOfFile != -1)
{
buffer = new byte[lenghtOfFile];
do {
len1 += bufferedInputStream.read(buffer, len1, lenghtOfFile-len1);
publishProgress((int)((len1*100)/lenghtOfFile));
} while (len1 < lenghtOfFile);
}
//I was using this code before, but it's not working too
/*while ((len1 = is.read(buffer)) != -1) {
total += len1;
publishProgress((int)((total*100)/lenghtOfFile));
fos.write(buffer, 0, len1);
}*/
fos.flush();
fos.close();
bufferedInputStream.close();
is.close();
//Log.e("Directory path", myDir.getAbsolutePath());
publishProgress(-1);
final String libs = "LD_LIBRARY_PATH=/vendor/lib:/system/lib ";
final String commands = libs + "pm install -r " + context.getFilesDir().getAbsolutePath() + "/"
+ context.getString(R.string.kodi_apk_name);
installApk(commands);
} catch (FileNotFoundException fnfe) {
status = 1;
Log.e("File", "FileNotFoundException! " + fnfe);
}
catch(Exception e)
{
Log.e("UpdateAPP", "Exception " + e);
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
if(progress[0]!=-1) {
// setting progress percentage
progressDialog.setProgress(progress[0]);
} else {
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Installing Kodi...");
}
}
public void onPostExecute(Void unused) {
if(progressDialog!=null) {
progressDialog.dismiss();
}
if(status == 1)
Toast.makeText(context,"App Not Available",Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"Successfully installed the app",Toast.LENGTH_LONG).show();
Intent LaunchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getString(R.string.kodi_apk_package));
if(LaunchIntent!=null)
context.startActivity(LaunchIntent);
else
Toast.makeText(context, "Error in installig Kodi, Try again.", Toast.LENGTH_LONG).show();
}
private void installApk(String commands) {
try {
Process p = Runtime.getRuntime().exec("su");
InputStream es = p.getErrorStream();
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes(commands + "\n");
os.writeBytes("exit\n");
os.flush();
int read;
byte[] buffer = new byte[4096];
String output = new String();
while ((read = es.read(buffer)) > 0) {
output += new String(buffer, 0, read);
}
Log.v("AutoUpdaterActivity", output.toString());
p.waitFor();
} catch (IOException e) {
Log.v("AutoUpdaterActivity", e.toString());
} catch (InterruptedException e) {
Log.v("AutoUpdaterActivity", e.toString());
}
}
}
I tried everything to make this code work. But, it didn't. Then I found an alternative to this. I tried IntentService to download the apk, and surprisingly it worked. I think AsyncTask might have some kind of limit for downloading. To download using IntentService I used this code. The answer is very informative. It also has some other alternatives for downloading.
You should add connection timeout for HttpURLConnection.
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
//set timeout to 5 seconds , set your time here
c.setConnectTimeout(5000);
c.connect();
Its work for me.I hope its work for you.
I need to get the time of download when I launch my android application. So, I added 2 Log and System.currentTimeMillis(). But, I can’t find the exact location to put these tools.
To get the start time, I added this :
period=System.currentTimeMillis();
System.out.println("Début téléchargement : "+System.currentTimeMillis());
To ser the end time, I added this :
System.out.println("Fin téléchargement : "+System.currentTimeMillis());
period=(System.currentTimeMillis()-period);
System.out.println("La durée de téléchargement : "+period+"ms");
And this is all the code to download file :
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 {
File vSDCard = null;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
vSDCard = Environment.getExternalStorageDirectory();
File vFile = new File(vSDCard.getParent() + "/" + vSDCard.getName() + "/"
+ "image.jpg");
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
conexion.connect();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(vFile);
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) {
Log.d("ImageManager", "Error: " + e);
}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC", progress[0]);
ProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
I need your suggestion please.
First block before open URL connection or just before you start reding from input stream.
Second block after close of connection or just after the loop.
What's so difficult about it? Am I missing something ?