In this tutorial, we’ll create an android application which downloads a file from the URL using Retrofit.
To know the basics of Retrofit, visit this tutorial.

在本教程中,我们将创建一个Android应用程序,该应用程序使用Retrofit从URL下载文件。
要了解翻新的基础知识,请访问本教程 。

Android改造下载文件 (Android Retrofit Download File)

We can create a retrofit call in the following way in order to download file:

我们可以通过以下方式创建改造调用以下载文件:

@GET
Call<ResponseBody> downloadFileWithc(@Url String urlString);

We can pass the URL of the file we want to download. If we are downloading a file present in the resources we can do this:

我们可以传递要下载的文件的URL。 如果我们要下载资源中存在的文件,则可以执行以下操作:

@GET("/resource/path_to_file_with_extension")
Call<ResponseBody> downloadFileStatic();

It’s recommended to use a @Streaming annotation on top of the @GET for downloading files. Otherwise Retrofit would move the entire file into memory. Using @Streaming the bytes would be accessed currently without eating up the memory.

建议在@Streaming顶部使用@Streaming批注来下载文件。 否则,翻新会将整个文件移到内存中。 使用@Streaming可以在不占用内存的情况下当前访问字节。

When using @Streaming you must add the code that writes the downloaded data, into a separate thread.

使用@Streaming ,必须将写入下载数据的代码添加到单独的线程中。

Using the enqueue method we can start the request.
Inside it, we need to create an AsyncTask or use RxJava. We’ll go with the former in this tutorial.

使用enqueue方法,我们可以启动请求。
在其中,我们需要创建一个AsyncTask或使用RxJava。 在本教程中,我们将使用前者。

In the following android application that we are going to build, we’ll show the file download progress on a ProgressBar.

在下面将要构建的android应用程序中,我们将在ProgressBar上显示文件下载进度。

项目设置 (Project Setup)

Add the following dependencies to your app’s build.gradle:

将以下依赖项添加到应用程序的build.gradle中:

implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.okhttp3:okhttps:3.10.0'

Add the following permissions in your Manifest:

在清单中添加以下权限:

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

Following is how our Project Structure looks:

以下是我们的项目结构的外观:

码 (Code)

The code for the activity_main.xml layout is given below:

下面给出了activity_main.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/txtProgressPercent"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Downloaded 0%"android:textColor="@color/colorAccent"android:textStyle="bold"android:textAppearance="@style/Base.TextAppearance.AppCompat.Display1"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><ProgressBarandroid:id="@+id/progressBar"style="?android:attr/progressBarStyleHorizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="16dp"android:layout_marginRight="16dp"android:layout_marginTop="16dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/txtProgressPercent" /><Buttonandroid:id="@+id/button"style="@style/ButtonStyle"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="16dp"android:text="DOWNLOAD FILE"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/progressBar" /></android.support.constraint.ConstraintLayout>

We’ve set a style on the button in the styles.xml.

我们在styles.xml中的按钮上设置了样式。

The code for the RetrofitInterface.java class is given below:

下面给出了RetrofitInterface.java类的代码:

package com.journaldev.androidretrofitdownloadfileprogress;import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Streaming;
import retrofit2.http.Url;public interface RetrofitInterface {@Streaming@GETCall<ResponseBody> downloadFileByUrl(@Url String fileUrl);}

The code for the MainActivity.java class is given below:

MainActivity.java类的代码如下:

package com.journaldev.androidretrofitdownloadfileprogress;import android.Manifest;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;public class MainActivity extends AppCompatActivity {TextView txtProgressPercent;ProgressBar progressBar;Button btnDownloadFile;DownloadZipFileTask downloadZipFileTask;private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 101);txtProgressPercent = findViewById(R.id.txtProgressPercent);progressBar = findViewById(R.id.progressBar);btnDownloadFile = findViewById(R.id.button);btnDownloadFile.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {downloadZipFile();}});}private void downloadZipFile() {RetrofitInterface downloadService = createService(RetrofitInterface.class, "https://github.com/");Call<ResponseBody> call = downloadService.downloadFileByUrl("anupamchugh/AnimateTextAndImageView/archive/master.zip");call.enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, final Response<ResponseBody> response) {if (response.isSuccessful()) {Log.d(TAG, "Got the body for the file");Toast.makeText(getApplicationContext(), "Downloading...", Toast.LENGTH_SHORT).show();downloadZipFileTask = new DownloadZipFileTask();downloadZipFileTask.execute(response.body());} else {Log.d(TAG, "Connection failed " + response.errorBody());}}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {t.printStackTrace();Log.e(TAG, t.getMessage());}});}public <T> T createService(Class<T> serviceClass, String baseUrl) {Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).client(new OkHttpClient.Builder().build()).build();return retrofit.create(serviceClass);}private class DownloadZipFileTask extends AsyncTask<ResponseBody, Pair<Integer, Long>, String> {@Overrideprotected void onPreExecute() {super.onPreExecute();}@Overrideprotected String doInBackground(ResponseBody... urls) {//Copy you logic to calculate progress and callsaveToDisk(urls[0], "journaldev-project.zip");return null;}protected void onProgressUpdate(Pair<Integer, Long>... progress) {Log.d("API123", progress[0].second + " ");if (progress[0].first == 100)Toast.makeText(getApplicationContext(), "File downloaded successfully", Toast.LENGTH_SHORT).show();if (progress[0].second > 0) {int currentProgress = (int) ((double) progress[0].first / (double) progress[0].second * 100);progressBar.setProgress(currentProgress);txtProgressPercent.setText("Progress " + currentProgress + "%");}if (progress[0].first == -1) {Toast.makeText(getApplicationContext(), "Download failed", Toast.LENGTH_SHORT).show();}}public void doProgress(Pair<Integer, Long> progressDetails) {publishProgress(progressDetails);}@Overrideprotected void onPostExecute(String result) {}}private void saveToDisk(ResponseBody body, String filename) {try {File destinationFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename);InputStream inputStream = null;OutputStream outputStream = null;try {inputStream = body.byteStream();outputStream = new FileOutputStream(destinationFile);byte data[] = new byte[4096];int count;int progress = 0;long fileSize = body.contentLength();Log.d(TAG, "File Size=" + fileSize);while ((count = inputStream.read(data)) != -1) {outputStream.write(data, 0, count);progress += count;Pair<Integer, Long> pairs = new Pair<>(progress, fileSize);downloadZipFileTask.doProgress(pairs);Log.d(TAG, "Progress: " + progress + "/" + fileSize + " >>>> " + (float) progress / fileSize);}outputStream.flush();Log.d(TAG, destinationFile.getParent());Pair<Integer, Long> pairs = new Pair<>(100, 100L);downloadZipFileTask.doProgress(pairs);return;} catch (IOException e) {e.printStackTrace();Pair<Integer, Long> pairs = new Pair<>(-1, Long.valueOf(-1));downloadZipFileTask.doProgress(pairs);Log.d(TAG, "Failed to save the file!");return;} finally {if (inputStream != null) inputStream.close();if (outputStream != null) outputStream.close();}} catch (IOException e) {e.printStackTrace();Log.d(TAG, "Failed to save the file!");return;}}private void askForPermission(String permission, Integer requestCode) {if (ContextCompat.checkSelfPermission(MainActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);} else {ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);}} else if (ContextCompat.checkSelfPermission(MainActivity.this, permission) == PackageManager.PERMISSION_DENIED) {Toast.makeText(getApplicationContext(), "Permission was denied", Toast.LENGTH_SHORT).show();}}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {if (requestCode == 101)Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();} else {Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();}}
}

In the above code, we are downloading a GitHub repository zip file.

在上面的代码中,我们正在下载GitHub存储库zip文件。

We do the following list of things in the above code:

我们在上面的代码中执行以下操作:

  • Runtime Permissions – We need this for saving the file in our phone storage.运行时权限 –我们需要此权限才能将文件保存在手机存储中。
  • Building a Retrofit Service using OkHttp使用OkHttp构建改造服务
  • Downloading the file from the url in the Async by using response.body().使用response.body()从Async中的url下载文件。
  • Inside the AsyncTask, we create a public method doProgress in which we invoke the AsyncTask method publishProgress().在AsyncTask内,我们创建一个公共方法doProgress在其中调用AsyncTask方法publishProgress()。
  • publishProgress triggers the onProgressUpdate() method of AsyncTask from the doInBackground.publishProgress从doInBackground触发AsyncTask的onProgressUpdate()方法。
  • Doing so we can determine the progress of the file download and update it on the ProgressBar.这样我们就可以确定文件下载的进度,并在ProgressBar上对其进行更新。
  • The downloaded file path is set inside the downloads folder in the Internal Storage.下载的文件路径在内部存储器的downloads文件夹内设置。

The output of the application in action is given below:

实际应用程序的输出如下:

And a screenshot from our File manager proves that the file is downloaded:

来自我们的文件管理器的屏幕快照证明文件已下载:

This brings an end to this tutorial. You can download the project from the link below:

本教程到此结束。 您可以从下面的链接下载项目:

AndroidRetrofitDownloadFileProgressAndroidRetrofitDownloadFileProgress
Github Project LinkGithub项目链接

翻译自: https://www.journaldev.com/22475/android-retrofit-download-file-progress

Android Retrofit下载文件进度相关推荐

  1. ajax实现下载文件进度条及方法详解

    javascript使用ajax下载文件进度条实现 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml&qu ...

  2. Android实现下载文件(图片)显示进度

    这里是做笔记用,不做过多介绍: 1.布局代码:download.xml <?xml version="1.0" encoding="utf-8"?> ...

  3. Android Service下载文件并自定义通知提示下载

    最近要做一个更新sdk,里面用到了service后台下载,自定义通知提示下载进度,下面直接贴上代码. 下面是UpdateUtils.java ,告诉你如何使用 package com.cnziz.up ...

  4. 利用curl下载文件(进度条显示) 代码片段

    在项目中需要用到程序更新的功能,同事介绍说是curl中的开发库很不错,于是下载这个包测试了一下,确实不错.准备正式用到项目中,以下一个例子用于从互联网上抓取一个文件下载到本地,并加上进度条显示,做得挺 ...

  5. Android 多线程下载 显示进度 速度

    功能要求:从网络下载一APK应用,显示下载速度.进度,并安装应用. 运行效果图: 工程结构图: 很简单,就一个activity,一个更新UI的线程,一个下载线程加个文件处理类 主要代码: /***多线 ...

  6. android之下载文件

    使用场景:用tomcat搭建了一个文件服务器,然后在安卓端去下载文件. 使用技术:使用 HttpURLConnection 建立http连接,并下载 package com.example.facec ...

  7. java 下载文件 进度条_使用处理程序下载文件时显示百分比的进度条

    我想在按钮上单击下载 .EXE 文件并在网页上显示下载进度条而不是浏览器进度条 . 这个开发背后的想法是浏览器在他的下载管理器中隐藏它的下载进度条 . 我想在下载达到100%后自动运行.EXE . 我 ...

  8. Android Ftp 下载文件:服务端搭建,客户端编写使用详情

    一  FTP与HTTP HTTP是超文本传输协议:面向网页的. FTP是File Transfer Protocol,文件传输协议:面向文件的. 1.FTP (1)FTP比HTTP复杂 FTP和HTT ...

  9. Android 多线程下载文件原理霸气解析介绍 -----文件的下载(3)

    1.首先我们先创建好下载的位置–根据url创建文件. /*** <p>Title: FlieStorageManager</p >* <p>Description: ...

最新文章

  1. 福利 | 爱德华·阿什福德·李:人类与AI技术将是共生关系
  2. golang适合做什么_什么八字适合做销售 适合做销售的八字特征
  3. 第二十五章补充内容 5 不能为0的变量
  4. 后台系统应该具备的素养
  5. linux tlhelp32.h,CreateToolhelp32Snapshot
  6. PaddleOCR服务器端部署C++ cpu或者gpu进行预测
  7. flex弹性布局学习总结
  8. LINUX下载编译lame
  9. 用科学计算器求均值与方差(超详细)(概率论中使用)
  10. 输出方波c语言程序,产生锯齿波以及方波的C程序
  11. 英语3500词(一)university life主题(2022.1.13)
  12. Python基础模块:图像处理模块@PIL(批量分类处理图片及添加水印)
  13. 云重磅 | 阿里巴巴平均每天纳税超1.4亿;谷歌、Face book与AWS将共建美欧新海底电缆;阿里发布谣言粉碎机:1秒辨真伪...
  14. win10更新至1909版本后,Primo Ramdisk失效的解决方案
  15. js数组的方法和扩展运算符
  16. C#中sealed的用法
  17. AE C# 图片标注背景透明
  18. 文末有福利 | IT从业者应关注哪些技术热点?
  19. 关于js中sort排序的用法
  20. 郑州尚学堂:Java培训:变量类型

热门文章

  1. 配置Hadoop开发环境(Eclipse)
  2. SQL语法集锦一:SQL语句实现表的横向聚合
  3. 【转】Android 中的 Service 全面总结
  4. Web页面打印及GridView导出到Excel
  5. JS+CSS实现Dock menu(MacOS菜单导航效果)
  6. [转载] python 如何判断中文的字符串长度
  7. [转载] python int 幂函数_Python中对数和幂函数的不精确结果
  8. quatus ii------调试利器 SignalTap II简介(基于TIGER BOARD 板子)
  9. 浅谈es6 promise
  10. 在Java下连接SQLite数据库