Como baixar um arquivo com uma barra de progresso no Android
O download de arquivos é uma tarefa comum em aplicativos Android, mas às vezes você pode querer mostrar ao usuário quanto do arquivo foi baixado e quanto tempo levará para terminar. É aqui que uma barra de progresso é útil. Uma barra de progresso é um indicador visual que mostra a porcentagem de conclusão de uma operação, como o download de um arquivo.
Neste artigo, mostraremos três maneiras de baixar um arquivo com uma barra de progresso no Android: usando AsyncTask e ProgressDialog, usando WorkManager e NotificationManager e usando bibliotecas de terceiros.
download file with progress bar android
Download Zip: https://urllio.com/2vRIJK
Usando AsyncTask e ProgressDialog
AsyncTask é uma classe que permite executar tarefas em segundo plano e atualizar o thread de interface do usuário com os resultados. ProgressDialog é uma caixa de diálogo que mostra um indicador de progresso e uma mensagem opcional.
Para usar AsyncTask e ProgressDialog para baixar um arquivo com uma barra de progresso, siga estas etapas:
Declare ProgressDialog e DownloadTask como campos membros de sua atividade.
ProgressDialog mProgressDialog; Tarefa de download Tarefa de download;
Instancie o ProgressDialog e o DownloadTask no método onCreate.
mProgressDialog = new ProgressDialog(this); mProgressDialog.setMessage("Baixando arquivo..."); mProgressDialog.setIndeterminate(falso); mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mProgressDialog.setCancelable(true); downloadTask = new DownloadTask(este);
Execute o DownloadTask com a URL do arquivo que deseja baixar.
downloadTask.execute("
Implemente os métodos doInBackground, onProgressUpdate e onPostExecute do DownloadTask.
classe privada DownloadTask estende AsyncTask contexto de contexto privado; privado PowerManager.WakeLock mWakeLock; public DownloadTask(Context context) this.context = context; @Override String protegida doInBackground(String...sUrl) InputStream input = null; Saída OutputStream = nulo; conexão HttpURLConnection = null; tente URL url = novo URL(sUrl[0]); conexão = (HttpURLConnection) url.openConnection(); connection.connect(); // verifique o código de resposta HTTP if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) return "Servidor retornou HTTP " + connection.getResponseCode() + " " + connection.getResponseMessage(); // obtém o tamanho do arquivo int fileLength = connection.getContentLength(); // baixe o arquivo input = connection.getInputStream(); output = new FileOutputStream("/sdcard/arquivo.zip"); byte dados[] = novo byte[4096]; longo total = 0; contagem int; while ((count = input.read(data)) != -1) // Peço desculpas pela demora, estava trabalhando no restante do artigo. Aqui está o que tenho até agora: // cancelar se a tarefa for cancelada if (isCancelled()) input.close(); retornar nulo; total += contagem; // publicar o progresso if (fileLength > 0) // somente se o comprimento total for conhecido publishProgress((int) (total * 100 / fileLength)); output.write(dados, 0, contagem); catch (Exception e) return e.toString(); finalmente tente if (saída != null) saída.close(); if (input != null) input.close(); catch (IOException ignorado) if (conexão != null) connection.disconnect(); retornar nulo; @Override protected void onProgressUpdate(Integer...progresso) super.onProgressUpdate(progresso); // define o andamento do diálogo mProgressDialog.setProgress(progress[0]); @Override protected void onPostExecute(String result) // dispensa a caixa de diálogo mProgressDialog.dismiss(); if (resultado != null) Toast.makeText(context,"Erro de download: "+resultado, Toast.LENGTH_LONG).show(); else Toast.makeText(context,"Arquivo baixado", Toast.LENGTH_SHORT).show();
Usando WorkManager e NotificationManager
WorkManager é uma biblioteca que permite agendar e executar tarefas em segundo plano que podem ser adiadas e garantidas para serem executadas. NotificationManager é um serviço do sistema que gerencia as notificações.
Para usar o WorkManager e o NotificationManager para baixar um arquivo com uma barra de progresso, siga estas etapas:
Adicione a dependência do WorkManager ao arquivo build.gradle do seu aplicativo.
dependências implementação "androidx.work:work-runtime:2.7.1"
Crie uma classe Worker que estenda ListenableWorker e substitua o método startWork.
public class DownloadWorker extends ListenableWorker public static final String KEY_FILE_URL = "file_url"; public static final String KEY_FILE_NAME = "file_name"; public static final String KEY_NOTIFICATION_ID = "notification_id"; string final estática pública KEY_NOTIFICATION_CHANNEL_ID = "notification_channel_id"; final estático privado int BUFFER_SIZE = 4096; gerenciador de notificações privado mNotificationManager; privado NotificationCompat.Builder mNotificationBuilder; public DownloadWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) super(context, workerParams); @NonNull @Override public ListenableFuture startWork() // obtém os dados de entrada String fileUrl = getInputData().getString(KEY_FILE_URL); String fileName = getInputData().getString(KEY_FILE_NAME); int notificationId = getInputData().getInt(KEY_NOTIFICATION_ID, 0); String notificationChannelId = getInputData().getString(KEY_NOTIFICATION_CHANNEL_ID); // criar um gerenciador de notificação e um construtor de notificação mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); mNotificationBuilder = new NotificationCompat.Builder(getApplicationContext(), notificationChannelId) .setContentTitle("Baixando arquivo...") .setContentText(fileName) .setSmallIcon(android.R.drawable.stat_sys_download) .setPriority(NotificationCompat.PRIORITY_LOW) .setProgress(0, 0, true) .setOngoing(true); // mostra a notificação mNotificationManager.notify(notificationId, mNotificationBuilder.build()); // cria um futuro para retornar o resultado do trabalho SettableFuture futuro = SettableFuture.create(); // baixe o arquivo em um thread separado new Thread(new Runnable() @Override public void run() InputStream input = null; OutputStream output = null; HttpURLConnection connection = null; try URL url = new URL(fileUrl); connection = (HttpURLConnection) url.openConnection(); connection.connect(); // verifique o código de resposta HTTP if (connection.getResponseCode() != Http URLConnection.HTTP_OK) future.set(Result.failure()); return; // obtém o tamanho do arquivo int fileLength = connection.getContentLength(); // baixa o arquivo input = connection.getInputStream(); output = new FileOutputStream("/sdcard/" + fileName); byte data[] = new byte[BUFFER_SIZE]; longo total = 0; contagem int; while ((count = input.read(data)) != -1) // cancela se o trabalho for interrompido if (isStopped()) input.close(); future.set(Result.failure()); retornar; total += contagem; // atualiza a notificação com o progresso if (fileLength > 0) // somente se o comprimento total for conhecido mNotificationBuilder.setProgress(100 , (int) (total * 100 / fileLength)); mNotificationManager.notify(notificationId, mNotificationBuilder.build()); output.write(data, 0, count); //defina o resultado como sucesso future.set(Result.success()); catch (Exception e) // define o resultado como falha future.set(Result.failure()); finalmente tente if (saída != null) saída.close(); if (input != null) input.close(); catch (IOException ignorado) if (conexão != null) connection.disconnect(); ).começar(); // retorna o futuro return future; }
Crie um NotificationChannel para Android O e superior.
private void createNotificationChannel() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) NotificationChannel channel = new NotificationChannel( "download_channel", "Download Channel", NotificationManager.IMPORTANCE_LOW); channel.setDescription("Canal de notificação para baixar arquivos"); NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(canal);
Enfileirar o DownloadWorker com os dados de entrada e as restrições.
private void downloadFile(String fileUrl, String fileName) // cria os dados de entrada Data inputData = new Data.Builder() .putString(DownloadWorker.KEY_FILE_URL, fileUrl) .putString(DownloadWorker.KEY_FILE_NAME, fileName) .putInt(DownloadWorker.KEY_NOTIFICATION_ID, 1) .putString(DownloadWorker.KEY_NOTIFICA TION_CHANNEL_ID, "download_channel") .build(); // criar as restrições Constraints constraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .build(); // cria a solicitação de trabalho OneTimeWorkRequest downloadRequest = new OneTimeWorkRequest.Builder(DownloadWorker.class) .setInputData(inputData) .setConstraints(constraints) .build(); // enfileirar a solicitação de trabalho WorkManager.getInstance(this).enqueue(downloadRequest);
Usando bibliotecas de terceiros
Se você não deseja lidar com os detalhes de baixo nível do download de arquivos com uma barra de progresso, pode usar algumas das bibliotecas de terceiros que fornecem essa funcionalidade. Aqui estão duas opções:
Biblioteca
Características
Uso
FileDownloader
- API simples e flexível- Callbacks e notificações de progresso- Pausar e retomar o suporte- Vários downloads e filas- Cabeçalhos personalizados e configurações de conexão
// inicializa a biblioteca FileDownloader.setup(this); // cria uma tarefa de download BaseDownloadTask task = FileDownloader.getImpl().create(fileUrl) .setPath(filePath) .setListener(new FileDownloadListener() @Override protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) // atualiza UI com estado pendente @Override protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) // atualização da interface do usuário com progresso @Override void protegido concluído(Tarefa BaseDownloadTask) // atualização da interface do usuário com estado concluído @Override protegido void pausado(tarefa BaseDownloadTask, int soFarBytes, int totalBytes) // atualização da interface do usuário com estado pausado @Override protegido void error(tarefa BaseDownloadTask, Throwable e) // atualização IU com estado de erro @Override protected void warning(BaseDownloadTask task) // trata o caso quando já existem algumas tarefas em execução ); // inicia a tarefa de download task.start();
PRDownloader
- API fácil de usar- Pausar e retomar o suporte- Vários downloads e filas- Ouvintes de progresso e notificações- Cabeçalhos personalizados e configurações de conexão- Suporta arquivos grandes
// inicializa a biblioteca PRDownloader.initialize(this); // cria uma solicitação de download DownloadRequest request = PRDownloader.download(fileUrl, dirPath, fileName) .build(); // define um ouvinte de progresso request.setOnProgressListener(new OnProgressListener() @Override public void onProgress(Progress progress) // atualiza a IU com progresso ); // define um ouvinte de status request.setStatusListener(new OnStatusListener() @Override public void onDownloadComplete() // atualiza a IU com o estado concluído @Override public void onError(Error error) // atualiza a IU com o estado de erro ); // inicia a solicitação de download request.start();
Conclusão
Neste artigo, mostramos três maneiras de baixar um arquivo com uma barra de progresso no Android: usando AsyncTask e ProgressDialog, usando WorkManager e NotificationManager e usando bibliotecas de terceiros. Cada método tem suas próprias vantagens e desvantagens, então você pode escolher aquele que se adapta às suas necessidades e preferências.
Algumas dicas e recomendações para baixar arquivos com barra de progresso no Android são:
Sempre verifique a disponibilidade da rede e a permissão de armazenamento antes de iniciar o download.
Sempre trate os possíveis erros e exceções que podem ocorrer durante o download.
Sempre cancele a tarefa ou solicitação de download quando o usuário sair do aplicativo ou da atividade.
Sempre use um identificador exclusivo para cada tarefa ou solicitação de download para evitar conflitos ou duplicatas.
Sempre teste seu aplicativo em diferentes dispositivos e condições de rede para garantir uma experiência de usuário tranquila.
perguntas frequentes
Como posso mostrar uma barra de progresso em um item RecyclerView?Você pode usar um widget ProgressBar em seu layout de item RecyclerView e atualizar seu valor de progresso no método onBindViewHolder de seu adaptador RecyclerView. Você também pode usar uma exibição personalizada ou uma biblioteca que forneça uma barra de progresso circular ou horizontal.
Como posso pausar e retomar uma tarefa ou solicitação de download?Se você estiver usando AsyncTask, poderá chamar cancel(true) no objeto DownloadTask para pausar o download e executá-lo novamente com a mesma URL para retomá-lo. Se você estiver usando o WorkManager, poderá chamar cancelWorkById(id) na instância do WorkManager para pausar o download e enfileirar novamente com os mesmos dados de entrada para retomá-lo. Se você estiver usando uma biblioteca de terceiros, poderá usar os métodos de pausa e retomada fornecidos pela biblioteca.
Como posso baixar vários arquivos com uma barra de progresso?Se você estiver usando AsyncTask, poderá criar vários objetos DownloadTask e executá-los em modo paralelo ou serial. Se você estiver usando o WorkManager, poderá criar vários objetos OneTimeWorkRequest e enfileira-los em uma instância WorkContinuation ou WorkManager. Se você estiver usando uma biblioteca de terceiros, poderá usar os recursos de fila ou lote fornecidos pela biblioteca.
Como posso mostrar a velocidade de download e o tempo restante na barra de progresso?Você pode calcular a velocidade de download dividindo o número de bytes baixados pelo tempo decorrido e o tempo restante dividindo o número de bytes restantes pela velocidade de download. Você pode então formatar esses valores e exibi-los no ProgressDialog ou no NotificationCompat.Builder.
Como posso personalizar a aparência da barra de progresso?Você pode usar diferentes estilos e atributos para o widget ProgressDialog ou ProgressBar, como indeterminate, max, progressDrawable, etc. Você também pode usar um layout personalizado ou uma biblioteca que forneça diferentes temas e animações para a barra de progresso.
0517a86e26
Comments