File download progress bar in android - android

How to show the remaining KB's of file is to be downloaded in progress bar in android.
e.g 12kb/120kb is remaining..then 97kb/120kb...etc
Can we have this progress dialog as shown in the image

class DownloadFileAsync extends AsyncTask<String, String, String> {
private ProgressDialog mProgressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(UrlTestActivity.this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
for (int i = 0; i < 3; i++) {
URL url = new URL("http://nodeload.github.com/nexes/Android-File-Manager/zipball/master");
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream is = url.openStream();
File testDirectory = new File(Environment.getExternalStorageDirectory() + "/Folder");
if (!testDirectory.exists()) {
testDirectory.mkdir();
}
FileOutputStream fos = new FileOutputStream(testDirectory+ "/"+(i+100)+".zip");
byte data[] = new byte[1024];
long total = 0;
int progress = 0;
while ((count = is.read(data)) != -1) {
total += count;
int progress_temp = (int) total * 100 / lenghtOfFile;
publishProgress(""+ progress_temp);
if (progress_temp % 10 == 0 && progress != progress_temp) {
progress = progress_temp;
}
fos.write(data, 0, count);
}
is.close();
fos.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);
}
}

The best way what you have described is to perform the download using an AsyncTask. In the onProgressUpdate method, you can update a ProgressDialog to indicate the user the percentage of completion. It will look like that:

progressDialog.setMax(fileLength/1000);
publishProgress(String.valueOf(total /1000));
The below code is only available after API 11
progressDialog. setProgressNumberFormat ("%1d kb of %2d kb");

Take a look at http://developer.android.com/guide/topics/ui/dialogs.html#ProgressDialog

You can use a progress dialog, as discussed in the docs. Alternatively (and perhaps more elegantly), you can use a progress indicator in your activity's title bar. In your activity, before calling setContentView, add this line:
requestWindowFeature(Window.FEATURE_PROGRESS);
Then by calling setProgress(int) you can indicate progress. When progress reaches 10000, the progress indicator in the title bar fades away. Note that if you determine progress in a non-UI thread, you should use a Handler to call setProgress.

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);
}

How to avoid exception "Only the original thread that created a view hierarchy can touch its views"?

I am using AsyncTaskfor downloading video file I am update views inside the AsyncTask but exception arises "Only the original thread that created a view hierarchy can touch its views". Here is my sample code. Please check it and suggest me where I need correction.
The exception arises at these lines.
tvPercent.setText((int)per + "%");
tvSpeed.setText(networkSpeed+"kbps");
AsyncTask Class
public class DownloadFileFromURL extends AsyncTask<String, String, String> {
ProgressBar ProgBar;
TextView tvSpeed;
TextView tvPercent;
int downloadedSize = 0;
int totalSize = 0;
private long networkSpeed;
private long previousTime;
private long totalTime;
// public DownloadFileFromURL(ProgressBar pb)
// {
// ProgBar = pb;
//
// }
public DownloadFileFromURL(ProgressBar pb, TextView speed, TextView per)
{
ProgBar = pb;
tvSpeed = speed;
tvPercent = per;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
ProgBar.setProgress(0);
//ProgBar.setMax(100);
previousTime = System.currentTimeMillis();
}
#Override
protected String doInBackground(String... videoURL)
{
try
{
URL url = new URL(videoURL[0]);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//connect
urlConnection.connect();
File file = getOutputMediaFile(videoURL[0]);
FileOutputStream fileOutput = new FileOutputStream(file);
//Stream used for reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file which we are downloading
totalSize = urlConnection.getContentLength();
Log.e("Download", ""+totalSize);
ProgBar.setMax(totalSize);
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 )
{
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
// update the progressbar //
ProgBar.setProgress(downloadedSize);
float per = ((float)downloadedSize/totalSize) * 100;
// update the progress in percentage //
tvPercent.setText((int)per + "%");
totalTime = System.currentTimeMillis() - previousTime;
networkSpeed = downloadedSize / totalTime;
// update network speed //
tvSpeed.setText(networkSpeed+"kbps");
}
//close the output stream when complete //
fileOutput.close();
downloadedSize = 0;
totalSize = 0;
}
catch (final MalformedURLException e)
{
e.printStackTrace();
}
catch (final IOException e)
{
e.printStackTrace();
}
catch (final Exception e)
{
e.printStackTrace();
}
return null;
}
protected void onProgressUpdate(String... progress)
{
// setting progress percentage
//ProgBar.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String file_url)
{
}
}
You can update UI only from the main thread. Move tvPercent.setText((int)per + "%"); to onProgressUpdate and call publishProgress(.) in doInBackground whenever you want to update the text.
I Fetched same problem many time then finally i got final solution for this problem.
remove all code that that change xml or update layout xml file from background method do it on post execute method.
AsyncTask does its main work(in doInBackground method) on a separate thread, but only the main thread can access the user interface. Code in doInBackground can not access the user interface.
The methodes onPreExecute, onProgressUpdate, onPostExecute is invoked on the main thread. Do any access to the user interface in these methods.
Call publishProgress in doInBackground to invoke onProgressUpdate on the main thread.
Read all about AsyncTask here.

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.

progress dialog for downloading pics

I am downloading roughly 231 pics and would like to have a progress dialog say downloading pics please wait until all the pics are available and then disappear. How would I go about doing this?
protected class DownloadFile extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... url)
{
int count;
try
{
URL url1 = new URL(url[0]);
URLConnection conexion = url1.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url1.openStream());
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1)
{
total += count;
// publishing the progress....
publishProgress((int)(total*100/lenghtOfFile));
}
input.close();
}
catch (Exception e)
{
}
return null;
}
public void onProgressUpdate(Integer... values)
{
super.onProgressUpdate(values);
// here you will have to update the progressbar
// with something like
setProgress(numPokemon);
}
}
I think u have dont wrong thing,
show progress dialog in onpreExecute() , ur logic in doinBackground() and dismiss progress dialog in onPostExecute().
Hope u get it
try this ::
class AddTask extends AsyncTask<Void, Void, Void> {
ProgressDialog pDialog = ProgressDialog.show(Recording.this,"Please wait...", "Retrieving data ...", true);
protected void onPreExecute() {
pDialog.setIndeterminate(true);
pDialog.setCancelable(false);
pDialog.show();
SaxParser(Username,Password);
}
protected Void doInBackground(Void... unused) {
// your code
return(null);
}
protected void onPostExecute(Void unused) {
pDialog.dismiss();
}
}

Categories

Resources