Scarica un file con Android e mostra i progressi in un ProgressDialog


Sto cercando di scrivere una semplice applicazione che viene aggiornata. Per questo ho bisogno di una semplice funzione che possa scaricare un file e mostrare l'avanzamento corrente in un ProgressDialog. So come fare ProgressDialog, ma non sono sicuro di come visualizzare l'avanzamento corrente e come scaricare il file in primo luogo.

Author: atish shimpi, 2010-06-12

12 answers

Ci sono molti modi per scaricare i file. Di seguito pubblicherò i modi più comuni; spetta a te decidere quale metodo è migliore per la tua app.

1. Usa AsyncTask e mostra l'avanzamento del download in una finestra di dialogo

Questo metodo ti consentirà di eseguire alcuni processi in background e aggiornare l'interfaccia utente allo stesso tempo (in questo caso, aggiorneremo una barra di avanzamento).

Questo è un codice di esempio:

// declare the dialog as a member field of your activity
ProgressDialog mProgressDialog;

// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);

// execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(YourActivity.this);
downloadTask.execute("the url to the file you want to download");

mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialog) {
        downloadTask.cancel(true);
    }
});

Il {[13] } sarà simile a questo:

// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {

    private Context context;
    private PowerManager.WakeLock mWakeLock;

    public DownloadTask(Context context) {
        this.context = context;
    }

    @Override
    protected String doInBackground(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();

            // download the file
            input = connection.getInputStream();
            output = new FileOutputStream("/sdcard/file_name.extension");

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

Il metodo sopra (doInBackground) viene eseguito sempre su un thread in background. Non dovresti fare alcuna attività dell'interfaccia utente lì. D'altra parte, onProgressUpdate e onPreExecute vengono eseguiti sul thread dell'interfaccia utente, quindi è possibile modificare la barra di avanzamento:

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // take CPU lock to prevent CPU from going off if the user 
        // presses the power button during download
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
             getClass().getName());
        mWakeLock.acquire();
        mProgressDialog.show();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        // if we get here, length is known, now set indeterminate to false
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgress(progress[0]);
    }

    @Override
    protected void onPostExecute(String result) {
        mWakeLock.release();
        mProgressDialog.dismiss();
        if (result != null)
            Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
        else
            Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
    }

Per farlo funzionare, è necessario il permesso WAKE_LOCK.

<uses-permission android:name="android.permission.WAKE_LOCK" />

2. Scarica dal servizio

La grande domanda qui è: come posso aggiornare la mia attività da un servizio?. Nel prossimo esempio useremo due classi di cui potresti non essere a conoscenza: ResultReceiver e IntentService. ResultReceiver è quella che ci permetterà di aggiornare il nostro thread da un servizio; IntentService ' e una sottoclasse di Service che genera un thread di sfondo per il proprio lavoro (si dovrebbe sapere che un Service viene eseguito effettivamente nello stesso thread della tua app; quando si estende Service, manualmente, è necessario generare il nuovo thread per eseguire le operazioni di blocco CPU).

Il servizio di download può essere simile a questo:

public class DownloadService extends IntentService {
    public static final int UPDATE_PROGRESS = 8344;
    public DownloadService() {
        super("DownloadService");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        String urlToDownload = intent.getStringExtra("url");
        ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
        try {
            URL url = new URL(urlToDownload);
            URLConnection connection = url.openConnection();
            connection.connect();
            // this will be useful so that you can show a typical 0-100% progress bar
            int fileLength = connection.getContentLength();

            // download the file
            InputStream input = new BufferedInputStream(connection.getInputStream());
            OutputStream output = new FileOutputStream("/sdcard/BarcodeScanner-debug.apk");

            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                Bundle resultData = new Bundle();
                resultData.putInt("progress" ,(int) (total * 100 / fileLength));
                receiver.send(UPDATE_PROGRESS, resultData);
                output.write(data, 0, count);
            }

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

        Bundle resultData = new Bundle();
        resultData.putInt("progress" ,100);
        receiver.send(UPDATE_PROGRESS, resultData);
    }
}

Aggiungi il servizio al manifest:

<service android:name=".DownloadService"/>

E l'attività sarà simile a questo:

// initialize the progress dialog like in the first example

// this is how you fire the downloader
mProgressDialog.show();
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("url", "url of the file to download");
intent.putExtra("receiver", new DownloadReceiver(new Handler()));
startService(intent);

Qui è stato ResultReceiver viene a giocare:

private class DownloadReceiver extends ResultReceiver{
    public DownloadReceiver(Handler handler) {
        super(handler);
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        super.onReceiveResult(resultCode, resultData);
        if (resultCode == DownloadService.UPDATE_PROGRESS) {
            int progress = resultData.getInt("progress");
            mProgressDialog.setProgress(progress);
            if (progress == 100) {
                mProgressDialog.dismiss();
            }
        }
    }
}

2.1 Utilizzare la libreria Groundy

Groundy è una libreria che fondamentalmente ti aiuta a eseguire pezzi di codice in un servizio in background e si basa sul concetto ResultReceiver mostrato sopra. Questa libreria è deprecata al momento. Questo è il modo in cui l'intero codice sarà simile a:

L'attività in cui si sta mostrando la finestra di dialogo...

public class MainActivity extends Activity {

    private ProgressDialog mProgressDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViewById(R.id.btn_download).setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                String url = ((EditText) findViewById(R.id.edit_url)).getText().toString().trim();
                Bundle extras = new Bundler().add(DownloadTask.PARAM_URL, url).build();
                Groundy.create(DownloadExample.this, DownloadTask.class)
                        .receiver(mReceiver)
                        .params(extras)
                        .queue();

                mProgressDialog = new ProgressDialog(MainActivity.this);
                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                mProgressDialog.setCancelable(false);
                mProgressDialog.show();
            }
        });
    }

    private ResultReceiver mReceiver = new ResultReceiver(new Handler()) {
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            super.onReceiveResult(resultCode, resultData);
            switch (resultCode) {
                case Groundy.STATUS_PROGRESS:
                    mProgressDialog.setProgress(resultData.getInt(Groundy.KEY_PROGRESS));
                    break;
                case Groundy.STATUS_FINISHED:
                    Toast.makeText(DownloadExample.this, R.string.file_downloaded, Toast.LENGTH_LONG);
                    mProgressDialog.dismiss();
                    break;
                case Groundy.STATUS_ERROR:
                    Toast.makeText(DownloadExample.this, resultData.getString(Groundy.KEY_ERROR), Toast.LENGTH_LONG).show();
                    mProgressDialog.dismiss();
                    break;
            }
        }
    };
}

A GroundyTask implementazione utilizzata da Groundy per scaricare il file e mostrare lo stato di avanzamento:

public class DownloadTask extends GroundyTask {    
    public static final String PARAM_URL = "com.groundy.sample.param.url";

    @Override
    protected boolean doInBackground() {
        try {
            String url = getParameters().getString(PARAM_URL);
            File dest = new File(getContext().getFilesDir(), new File(url).getName());
            DownloadUtils.downloadFile(getContext(), url, dest, DownloadUtils.getDownloadListenerForTask(this));
            return true;
        } catch (Exception pokemon) {
            return false;
        }
    }
}

E basta aggiungere questo al manifesto:

<service android:name="com.codeslap.groundy.GroundyService"/>
Non potrebbe essere più facile, credo. Basta prendere l'ultimo jar da Github e si è pronti ad andare. Tieni presente che lo scopo principale di Groundy è quello di effettuare chiamate a api REST esterne in un servizio in background e pubblicare facilmente i risultati nell'interfaccia utente. Se stai facendo qualcosa del genere nella tua app, potrebbe essere davvero utile.

2.2 Use https://github.com/koush/ion

3. UsaDownloadManager class (GingerBread e solo versioni successive)

GingerBread ha portato una nuova funzionalità, DownloadManager, che consente di scaricare facilmente i file e delegare il duro lavoro di gestione di thread, flussi, ecc. al sistema.

Per prima cosa, vediamo un metodo di utilità:

/**
 * @param context used to check the device version and DownloadManager information
 * @return true if the download manager is available
 */
public static boolean isDownloadManagerAvailable(Context context) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
        return true;
    }
    return false;
}
Il nome del metodo

Spiega tutto. Una volta che sei sicuro che DownloadManager è disponibile, puoi fare qualcosa del genere:

String url = "url you want to download";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription("Some descrition");
request.setTitle("Some title");
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    request.allowScanningByMediaScanner();
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "name-of-the-file.ext");

// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);

Lo stato di avanzamento del download sarà mostrando nella barra di notifica.

Considerazioni finali

Primo e secondo metodo sono solo la punta dell'iceberg. Ci sono molte cose che devi tenere a mente se vuoi che la tua app sia robusta. Ecco un breve elenco:

  • È necessario verificare se l'utente dispone di una connessione Internet disponibile
  • Assicurarsi di avere le autorizzazioni giuste (INTERNET e WRITE_EXTERNAL_STORAGE); anche ACCESS_NETWORK_STATE se si desidera verificare la disponibilità di Internet.
  • Assicurarsi che la directory erano che si sta per scaricare i file esistono e ha le autorizzazioni di scrittura.
  • Se il download è troppo grande, potresti voler implementare un modo per riprendere il download se i tentativi precedenti non sono riusciti.
  • Gli utenti saranno grati se si consente loro di interrompere il download.

A meno che non sia necessario un controllo dettagliato del processo di download, considerare l'utilizzo di DownloadManager (3) perché gestisce già la maggior parte degli elementi sopra elencati.

Ma considera anche che le tue esigenze possono cambiare. Ad esempio, DownloadManager non fa cache di risposta . Scaricherà ciecamente lo stesso grande file più volte. Non c'è un modo semplice per risolverlo dopo il fatto. Dove se si inizia con una base HttpURLConnection (1, 2), quindi tutto ciò che serve è aggiungere un HttpResponseCache. Quindi lo sforzo iniziale di imparare gli strumenti standard di base può essere un buon investimento.

Questa classe è stata deprecata nel livello API 26. ProgressDialog è un modale finestra di dialogo, che impedisce all'utente di interagire con app. Invece di usare questa classe, dovresti usare un indicatore di avanzamento come ProgressBar, che può essere incorporato nell'interfaccia utente della tua app. Alternativamente, è possibile utilizzare una notifica per informare l'utente dello stato di avanzamento dell'attività. Per maggiori dettagli Link

 1744
Author: Cristian, 2018-07-09 12:29:31

Non dimenticare di aggiungere le autorizzazioni al tuo file manifest se stai scaricando cose da Internet!

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloandroid"
    android:versionCode="1"
    android:versionName="1.0">

        <uses-sdk android:minSdkVersion="10" />

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
        <uses-permission android:name="android.permission.INTERNET"></uses-permission>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
        <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

        <application 
            android:icon="@drawable/icon" 
            android:label="@string/app_name" 
            android:debuggable="true">

        </application>

</manifest>
 101
Author: Mnightmare, 2015-04-24 21:42:24

Sì il codice sopra funzionerà .Ma se stai aggiornando il tuo progressbar in onProgressUpdate di Asynctask e premi il pulsante indietro o finisci la tua attività AsyncTask perde la sua traccia con la tua interfaccia utente .E quando torni alla tua attività, anche se il download è in esecuzione in background non vedrai alcun aggiornamento sulla progressbar. Quindi su OnResume() prova a eseguire un thread come runOnUIThread con un'attività timer che aggiorna ur progressbar con i valori che si aggiornano dallo sfondo di esecuzione AsyncTask.

private void updateProgressBar(){
    Runnable runnable = new updateProgress();
    background = new Thread(runnable);
    background.start();
}

public class updateProgress implements Runnable {
    public void run() {
        while(Thread.currentThread()==background)
            //while (!Thread.currentThread().isInterrupted()) {
            try {
                Thread.sleep(1000); 
                Message msg = new Message();
                progress = getProgressPercentage();        
                handler.sendMessage(msg);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } catch (Exception e) {
        }
    }
}

private Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        progress.setProgress(msg.what);
    }
};

Non dimenticare di Distruggere il thread quando l'attività ur non è visibile.

private void destroyRunningThreads() {
    if (background != null) {
        background.interrupt();
        background=null;
    }
}
 29
Author: sheetal, 2016-12-28 17:14:33

Ti consiglio di usare il mio progetto Netroid, è basato su Volley. Ho aggiunto alcune funzionalità ad esso come il callback multi-eventi, la gestione del download dei file. Questo potrebbe essere di qualche aiuto.

 17
Author: VinceStyling, 2017-10-30 11:02:52

Ho modificato la classe AsyncTask per gestire la creazione di progressDialog nello stesso contesto .Penso che il codice seguente sarà più riutilizzabile. (può essere chiamato da qualsiasi attività basta passare contesto, file di destinazione, messaggio di dialogo)

public static class DownloadTask extends AsyncTask<String, Integer, String> {
    private ProgressDialog mPDialog;
    private Context mContext;
    private PowerManager.WakeLock mWakeLock;
    private File mTargetFile;
    //Constructor parameters :
    // @context (current Activity)
    // @targetFile (File object to write,it will be overwritten if exist)
    // @dialogMessage (message of the ProgresDialog)
    public DownloadTask(Context context,File targetFile,String dialogMessage) {
        this.mContext = context;
        this.mTargetFile = targetFile;
        mPDialog = new ProgressDialog(context);

        mPDialog.setMessage(dialogMessage);
        mPDialog.setIndeterminate(true);
        mPDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mPDialog.setCancelable(true);
        // reference to instance to use inside listener
        final DownloadTask me = this;
        mPDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                me.cancel(true);
            }
        });
        Log.i("DownloadTask","Constructor done");
    }

    @Override
    protected String doInBackground(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();
            }
            Log.i("DownloadTask","Response " + connection.getResponseCode());

            // 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(mTargetFile,false);

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                // allow canceling with back button
                if (isCancelled()) {
                    Log.i("DownloadTask","Cancelled");
                    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;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // take CPU lock to prevent CPU from going off if the user
        // presses the power button during download
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                getClass().getName());
        mWakeLock.acquire();

        mPDialog.show();

    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        // if we get here, length is known, now set indeterminate to false
        mPDialog.setIndeterminate(false);
        mPDialog.setMax(100);
        mPDialog.setProgress(progress[0]);

    }

    @Override
    protected void onPostExecute(String result) {
        Log.i("DownloadTask", "Work Done! PostExecute");
        mWakeLock.release();
        mPDialog.dismiss();
        if (result != null)
            Toast.makeText(mContext,"Download error: "+result, Toast.LENGTH_LONG).show();
        else
            Toast.makeText(mContext,"File Downloaded", Toast.LENGTH_SHORT).show();
    }
}
 15
Author: The Syrian, 2016-12-28 17:16:09

Ho trovato questo post sul blog molto utile, il suo utilizzo loopJ per scaricare il file, ha solo una semplice funzione, sarà utile per alcuni nuovi ragazzi Android.

 8
Author: chintan adatiya, 2014-08-01 14:55:06

Non dimenticare di sostituire "/sdcard..."di nuovo file("/mnt / scheda sd/...") altrimenti si otterrà un FileNotFoundException

 7
Author: ENSATE, 2014-02-10 00:17:04

Mentre stavo iniziando a imparare lo sviluppo di Android, avevo imparato che ProgressDialog è la strada da percorrere. Esiste il metodo setProgress di ProgressDialog che può essere richiamato per aggiornare il livello di avanzamento man mano che il file viene scaricato.

La cosa migliore che ho visto in molte app è che personalizzano gli attributi di questa finestra di avanzamento per dare un aspetto migliore alla finestra di avanzamento rispetto alla versione stock. Buono per mantenere l'utente impegnato con qualche animazione di come rana, elefante o simpatici gatti / cuccioli. Qualsiasi l'animazione con nella finestra di dialogo di avanzamento attira gli utenti e non hanno voglia di essere tenuti in attesa a lungo.

Scriverò un post sul blog su ProgressDialog e condividerò qui presto.

Modifica: Mostra la barra di avanzamento durante il download di un file in Android

 6
Author: Sandeep, 2016-12-28 17:13:45

Il mio consiglio personale è quello di utilizzare Dialogo di avanzamento e costruire prima dell'esecuzione , o iniziare a OnPreExecute(), pubblicare i progressi spesso se si utilizza lo stile orizzontale della barra di avanzamento della finestra di dialogo di avanzamento. La parte rimanente è quella di ottimizzare l'algoritmo di doInBackground.

 5
Author: Raju yourPepe, 2014-05-30 09:17:00

Usa la libreria di query Android, davvero molto interessante.Puoi cambiarlo per usare ProgressDialog come vedi in altri esempi, questo mostrerà la vista di avanzamento dal tuo layout e lo nasconderà dopo il completamento.

File target = new File(new File(Environment.getExternalStorageDirectory(), "ApplicationName"), "tmp.pdf");
new AQuery(this).progress(R.id.progress_view).download(_competition.qualificationScoreCardsPdf(), target, new AjaxCallback<File>() {
    public void callback(String url, File file, AjaxStatus status) {
        if (file != null) {
            // do something with file  
        } 
    }
});
 5
Author: Renetik, 2016-12-28 17:15:06

Permessi

  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission 
   android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Utilizzo di HttpURLConnection

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class DownloadFileUseHttpURLConnection extends Activity {

ProgressBar pb;
Dialog dialog;
int downloadedSize = 0;
int totalSize = 0;
TextView cur_val;
String dwnload_file_path =  
"http://coderzheaven.com/sample_folder/sample_file.png";
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button b = (Button) findViewById(R.id.b1);
    b.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
             showProgress(dwnload_file_path);

                new Thread(new Runnable() {
                    public void run() {
                         downloadFile();
                    }
                  }).start();
        }
    });
}

void downloadFile(){

    try {
        URL url = new URL(dwnload_file_path);
        HttpURLConnection urlConnection = (HttpURLConnection)   
 url.openConnection();

        urlConnection.setRequestMethod("GET");
        urlConnection.setDoOutput(true);

        //connect
        urlConnection.connect();

        //set the path where we want to save the file           
        File SDCardRoot = Environment.getExternalStorageDirectory(); 
        //create a new file, to save the downloaded file 
        File file = new File(SDCardRoot,"downloaded_file.png");

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

        runOnUiThread(new Runnable() {
            public void run() {
                pb.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 //
            runOnUiThread(new Runnable() {
                public void run() {
                    pb.setProgress(downloadedSize);
                    float per = ((float)downloadedSize/totalSize) *     
                    100;
                    cur_val.setText("Downloaded " + downloadedSize +  

                    "KB / " + totalSize + "KB (" + (int)per + "%)" );
                }
            });
        }
        //close the output stream when complete //
        fileOutput.close();
        runOnUiThread(new Runnable() {
            public void run() {
                // pb.dismiss(); // if you want close it..
            }
        });         

    } catch (final MalformedURLException e) {
        showError("Error : MalformedURLException " + e);        
        e.printStackTrace();
    } catch (final IOException e) {
        showError("Error : IOException " + e);          
        e.printStackTrace();
    }
    catch (final Exception e) {
        showError("Error : Please check your internet connection " +  
e);
    }       
}

void showError(final String err){
    runOnUiThread(new Runnable() {
        public void run() {
            Toast.makeText(DownloadFileDemo1.this, err,  
      Toast.LENGTH_LONG).show();
        }
    });
}

void showProgress(String file_path){
    dialog = new Dialog(DownloadFileDemo1.this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(R.layout.myprogressdialog);
    dialog.setTitle("Download Progress");

    TextView text = (TextView) dialog.findViewById(R.id.tv1);
    text.setText("Downloading file from ... " + file_path);
    cur_val = (TextView) dialog.findViewById(R.id.cur_pg_tv);
    cur_val.setText("Starting download...");
    dialog.show();

     pb = (ProgressBar)dialog.findViewById(R.id.progress_bar);
     pb.setProgress(0);
            pb.setProgressDrawable(
      getResources().getDrawable(R.drawable.green_progress));  
  }
}
 2
Author: vishnuc156, 2016-10-03 11:06:51

Sto aggiungendo un'altra risposta per un'altra soluzione che sto usando ora perché la query Android è così grande e non mantenuta per rimanere in salute. Così mi sono trasferito a questo https://github.com/amitshekhariitbhu/Fast-Android-Networking.

    AndroidNetworking.download(url,dirPath,fileName).build()
      .setDownloadProgressListener(new DownloadProgressListener() {
        public void onProgress(long bytesDownloaded, long totalBytes) {
            bar.setMax((int) totalBytes);
            bar.setProgress((int) bytesDownloaded);
        }
    }).startDownload(new DownloadListener() {
        public void onDownloadComplete() {
            ...
        }

        public void onError(ANError error) {
            ...
        }
    });
 2
Author: Renetik, 2017-08-28 18:39:42