Télécharger un fichier avec Android, et montrant la progression dans un ProgressDialog

j'essaie d'écrire une application simple qui est mise à jour. Pour cela, j'ai besoin d'une fonction simple qui peut télécharger un fichier et afficher la progression actuelle dans un ProgressDialog . Je sais comment faire le ProgressDialog , mais je ne sais pas comment afficher la progression actuelle et comment télécharger le fichier en premier lieu.

935
demandé sur atish shimpi 2010-06-12 14:22:56

12 réponses

il y a plusieurs façons de télécharger des fichiers. La suite, je vais poster plus souvent; c'est à vous de décider quelle méthode est la meilleure pour votre application.

1. Utilisez AsyncTask et afficher la progression du téléchargement dans un dialogue

cette méthode vous permettra d'exécuter certains processus de fond et de mettre à jour L'interface en même temps (dans ce cas, nous mettrons à jour une barre de progression).

Ceci est un exemple de code:

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

le AsyncTask ressemblera à ceci:

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

la méthode ci-dessus ( doInBackground ) fonctionne toujours sur un filetage d'arrière-plan. Vous ne devriez pas faire de tâches D'assurance-chômage là-bas. D'un autre côté ,le onProgressUpdate et le onPreExecute fonctionnent sur le fil UI, de sorte que vous pouvez changer la barre de progression:

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

pour cela, vous avez besoin de la permission WAKE_LOCK.

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

2. Télécharger à partir de Service

la grande question ici est: comment mettre à jour mon activité d'un service? . Dans l'exemple suivant, nous allons utiliser deux classes, vous ne pouvez pas être au courant: ResultReceiver et IntentService . ResultReceiver est celui qui nous permettra de mettre à jour notre thread à partir d'un service; IntentService est une sous-classe de Service qui produit un thread pour faire du travail de fond à partir de là (vous devriez savoir qu'un Service court en fait dans le même thread de votre application; lorsque vous prolongez Service , vous devez lancer manuellement de nouveaux threads pour exécuter les opérations de blocage CPU).

le service de téléchargement peut ressembler à ceci:

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

ajoutez le service à votre manifeste:

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

et l'activité ressemblera à ceci:

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

c'est Là que les ResultReceiver vient de jouer:

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 Utiliser Groundy bibliothèque

Groundy est une bibliothèque qui vous aide essentiellement à exécuter des morceaux de code dans un service de fond, et il est basé sur le concept ResultReceiver ci-dessus. Cette bibliothèque est dépréciée en ce moment. Voici à quoi ressemblerait le code entier :

l'activité où vous montrez le dialogue...

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

Un GroundyTask la mise en œuvre utilisée par les Groundy pour télécharger le fichier et de montrer les progrès accomplis:

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

et ajoutez ceci au manifeste:

<service android:name="com.codeslap.groundy.GroundyService"/>

ça ne peut pas être plus facile. Il suffit de prendre le dernier pot de Github et vous êtes prêt à aller. Gardez à l'esprit que Groundy ' s principal objectif est de faire des appels à des API de repos externes dans un contexte afficher facilement les résultats du service à L'IU. Si vous faites quelque chose comme cela dans votre application, il pourrait être vraiment utile.

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

3. Utiliser DownloadManager classe ( GingerBread et versions plus récentes uniquement)

GingerBread apporté une nouvelle fonctionnalité, DownloadManager , qui vous permet de télécharger des fichiers facilement et de déléguer le travail difficile de la manipulation des threads, flux, etc. pour le système.

tout d'abord, voyons une méthode d'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;
}

le nom de la méthode explique tout. Une fois que vous êtes sûr que DownloadManager est disponible, vous pouvez faire quelque chose comme ceci:

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

télécharger le progrès sera affiché dans la barre de notification.

dernières pensées

les première et deuxième méthodes ne sont que la pointe de l'iceberg. Il y a beaucoup de choses vous devez garder à l'esprit si vous voulez que votre application d'être robuste. Voici une brève liste:

  • , Vous devez vérifier si l'utilisateur a une connexion internet est disponible
  • assurez-vous d'avoir les bonnes permissions ( INTERNET et WRITE_EXTERNAL_STORAGE ); aussi ACCESS_NETWORK_STATE si vous voulez vérifier la disponibilité sur Internet.
  • assurez-vous que le répertoire où vous allez télécharger des fichiers existent et a les permissions d'écriture.
  • si le téléchargement est trop important, vous pouvez mettre en œuvre un moyen de reprendre le téléchargement si les tentatives précédentes ont échoué.
  • les utilisateurs seront reconnaissants si vous leur permettez d'interrompre le téléchargement.

sauf si vous avez besoin d'un contrôle détaillé du processus de téléchargement, alors envisagez d'utiliser DownloadManager (3) parce qu'il traite déjà la plupart des éléments énumérés ci-dessus.

mais aussi considérer que vos besoins peut changer. Par exemple, DownloadManager ne répond pas à la mise en cache . Il téléchargera aveuglément le même Gros Fichier plusieurs fois. Il n'y a pas de moyen facile de le réparer après les faits. Où si vous commencez par un HttpURLConnection (1, 2), alors tout ce dont vous avez besoin est d'ajouter un HttpResponseCache . Ainsi, l'effort initial d'apprentissage des outils standards de base peut être un bon investissement.

cette classe a été dépréciée au niveau API 26. ProgressDialog est un modal dialogue, qui évite à l'utilisateur d'interagir avec l'application. Plutôt de l'utilisation de cette classe, vous devez utiliser un indicateur de progression comme ProgressBar, qui peut être intégré dans L'interface utilisateur de votre application. Alternativement, vous pouvez utiliser une notification pour informer l'utilisateur de la tâche en cours. Pour plus de détails Lien

1744
répondu Cristian 2018-07-09 12:29:31

n'oubliez pas d'ajouter des permissions à votre fichier de manifestes si vous allez télécharger des trucs à partir d'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
répondu Mnightmare 2015-04-24 21:42:24

Oui le code ci-dessus fonctionnera .Mais si vous mettez à jour votre progressbar dans onProgressUpdate de Asynctask et que vous appuyez sur le bouton Retour ou que vous terminez votre activité AsyncTask perd sa trace avec votre UI .Et lorsque vous retournez à votre activité, même si le téléchargement est en cours d'exécution en arrière-plan, vous ne verrez aucune mise à jour sur progressbar. Donc, sur OnResume() essayer d'exécuter un thread comme runOnUIThread avec une tâche de minuterie qui met à jour ur progressbar avec des valeurs de mise à jour de la AsyncTask exécutées en arrière-plan.

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

N'oubliez pas de détruire le fil lorsque l'activité ur n'est pas visible.

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

je vous recommande d'utiliser mon projet Netroid , il est basé sur Volley . J'y ai ajouté des fonctionnalités telles que le rappel multi-événements, la gestion de téléchargement de fichiers. Cela pourrait être de quelque secours.

17
répondu VinceStyling 2017-10-30 11:02:52

j'ai modifié AsyncTask class pour gérer la création de progressDialog dans le même contexte .Je pense que code suivant sera plus réutilisable. (il peut être appelé à partir de n'importe quelle activité il suffit de passer le contexte,le fichier cible,le message de dialogue)

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
répondu The Syrian 2016-12-28 17:16:09

j'ai trouvé ce billet de blog très utile, son utilisation de loopJ pour télécharger le fichier, il a une seule fonction Simple, sera utile à certains nouveaux gars android.

8
répondu chintan adatiya 2014-08-01 14:55:06

Ne pas oublier de remplacer "/sdcard..."par nouveau Fichier ("/mnt/sdcard/...") sinon vous obtiendrez un FileNotFoundException

7
répondu ENSATE 2014-02-10 00:17:04

alors que je commençais à apprendre le développement android, j'avais appris que ProgressDialog est la voie à suivre. Il y a la méthode setProgress de ProgressDialog qui peut être invoquée pour mettre à jour le niveau de progression au fur et à mesure que le fichier est téléchargé.

le mieux que j'ai vu dans beaucoup d'applications est qu'ils personnalisent les attributs de ce dialogue de progrès pour donner un meilleur regard et une meilleure sensation à la boîte de dialogue de progrès que la version de stock. Bon à garder l'utilisateur engagé avec une certaine animation de comme la grenouille, l'éléphant ou les chats mignons/chiots. Toute animation dans le dialogue de progression attire les utilisateurs et ils n'ont pas envie d'attendre longtemps.

je vais écrire un billet de blog sur ProgressDialog et partager ici bientôt.

Edit: afficher la barre de progression lors du téléchargement d'un fichier sous android

6
répondu Sandeep 2016-12-28 17:13:45

mon conseil personnel est d'utiliser dialogue de progrès et de construire avant l'exécution , ou d'initier à OnPreExecute() , publier le progrès souvent si vous utilisez le style horizontal de barre de progrès de la boîte de dialogue de progrès. La partie restante est d'optimiser l'algorithme de doInBackground .

5
répondu Raju yourPepe 2014-05-30 09:17:00

utilisez Android Query library, très cool en effet.Vous pouvez le modifier pour utiliser ProgressDialog comme vous le voyez dans d'autres exemples, celui-ci affichera la vue de progression de votre mise en page et le masquera après achèvement.

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
répondu Renetik 2016-12-28 17:15:06

Autorisations

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

Utilisant 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
répondu vishnuc156 2016-10-03 11:06:51

je suis en train d'ajouter une autre réponse pour une autre solution que j'utilise maintenant parce que la requête Android est si grande et non maintenue pour rester en bonne santé. Alors j'ai déménagé dans ce 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
répondu Renetik 2017-08-28 18:39:42