Android使用OkHttp实现带进度的上传下载

先贴上MainActivity.java

package cn.edu.zafu.sample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;

import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import cn.edu.zafu.coreprogress.helper.ProgressHelper;
import cn.edu.zafu.coreprogress.listener.ProgressListener;
import cn.edu.zafu.coreprogress.listener.impl.UIProgressListener;

public class MainActivity extends AppCompatActivity {
    private static final OkHttpClient client = new OkHttpClient.Builder()
            //设置超时,不设置可能会报异常
            .connectTimeout(1000, TimeUnit.MINUTES)
            .readTimeout(1000, TimeUnit.MINUTES)
            .writeTimeout(1000, TimeUnit.MINUTES)
            .build();
    private Button upload,download;
    private ProgressBar uploadProgress,downloadProgeress;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        uploadProgress= (ProgressBar) findViewById(R.id.upload_progress);
        downloadProgeress= (ProgressBar) findViewById(R.id.download_progress);
        upload= (Button) findViewById(R.id.upload);
        download= (Button) findViewById(R.id.download);
        upload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                upload();
            }
        });
        download.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                download();
            }
        });
    }

    private void download() {
        //这个是非ui线程回调,不可直接操作UI
        final ProgressListener progressResponseListener = new ProgressListener() {
            @Override
            public void onProgress(long bytesRead, long contentLength, boolean done) {
                Log.e("TAG", "bytesRead:" + bytesRead);
                Log.e("TAG", "contentLength:" + contentLength);
                Log.e("TAG", "done:" + done);
                if (contentLength != -1) {
                    //长度未知的情况下回返回-1
                    Log.e("TAG", (100 * bytesRead) / contentLength + "% done");
                }
                Log.e("TAG", "================================");
            }
        };

        //这个是ui线程回调,可直接操作UI
        final UIProgressListener uiProgressResponseListener = new UIProgressListener() {
            @Override
            public void onUIProgress(long bytesRead, long contentLength, boolean done) {
                Log.e("TAG", "bytesRead:" + bytesRead);
                Log.e("TAG", "contentLength:" + contentLength);
                Log.e("TAG", "done:" + done);
                if (contentLength != -1) {
                    //长度未知的情况下回返回-1
                    Log.e("TAG", (100 * bytesRead) / contentLength + "% done");
                }
                Log.e("TAG", "================================");
                //ui层回调
                downloadProgeress.setProgress((int) ((100 * bytesRead) / contentLength));
                //Toast.makeText(getApplicationContext(), bytesRead + " " + contentLength + " " + done, Toast.LENGTH_LONG).show();
            }

            @Override
            public void onUIStart(long bytesRead, long contentLength, boolean done) {
                super.onUIStart(bytesRead, contentLength, done);
                Toast.makeText(getApplicationContext(),"start",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onUIFinish(long bytesRead, long contentLength, boolean done) {
                super.onUIFinish(bytesRead, contentLength, done);
                Toast.makeText(getApplicationContext(),"end",Toast.LENGTH_SHORT).show();
            }
        };

        //构造请求
        final Request request1 = new Request.Builder()
                .url("http://121.41.119.107:81/test/1.doc")
                .build();

        //包装Response使其支持进度回调
        ProgressHelper.addProgressResponseListener(client, uiProgressResponseListener).newCall(request1).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                Log.e("TAG", "error ", e);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                Log.e("TAG", response.body().string());
            }
        });
    }

    private void upload() {
        File file = new File("/sdcard/1.doc");
        //此文件必须在手机上存在,实际情况下请自行修改,这个目录下的文件只是在我手机中存在。

        //这个是非ui线程回调,不可直接操作UI
        final ProgressListener progressListener = new ProgressListener() {
            @Override
            public void onProgress(long bytesWrite, long contentLength, boolean done) {
                Log.e("TAG", "bytesWrite:" + bytesWrite);
                Log.e("TAG", "contentLength" + contentLength);
                Log.e("TAG", (100 * bytesWrite) / contentLength + " % done ");
                Log.e("TAG", "done:" + done);
                Log.e("TAG", "================================");
            }
        };

        //这个是ui线程回调,可直接操作UI
        final UIProgressListener uiProgressRequestListener = new UIProgressListener() {
            @Override
            public void onUIProgress(long bytesWrite, long contentLength, boolean done) {
                Log.e("TAG", "bytesWrite:" + bytesWrite);
                Log.e("TAG", "contentLength" + contentLength);
                Log.e("TAG", (100 * bytesWrite) / contentLength + " % done ");
                Log.e("TAG", "done:" + done);
                Log.e("TAG", "================================");
                //ui层回调
                uploadProgress.setProgress((int) ((100 * bytesWrite) / contentLength));
                //Toast.makeText(getApplicationContext(), bytesWrite + " " + contentLength + " " + done, Toast.LENGTH_LONG).show();
            }

            @Override
            public void onUIStart(long bytesWrite, long contentLength, boolean done) {
                super.onUIStart(bytesWrite, contentLength, done);
                Toast.makeText(getApplicationContext(),"start",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onUIFinish(long bytesWrite, long contentLength, boolean done) {
                super.onUIFinish(bytesWrite, contentLength, done);
                Toast.makeText(getApplicationContext(),"end",Toast.LENGTH_SHORT).show();
            }
        };

        //构造上传请求,类似web表单
        RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("hello", "android")
                .addFormDataPart("photo", file.getName(), RequestBody.create(null, file))
                .addPart(Headers.of("Content-Disposition", "form-data; name=\"another\";filename=\"another.dex\""), RequestBody.create(MediaType.parse("application/octet-stream"), file))
                .build();

        //进行包装,使其支持进度回调
        final Request request = new Request.Builder().url("http://121.41.119.107:81/test/result.php").post(ProgressHelper.addProgressRequestListener(requestBody, uiProgressRequestListener)).build();
        //开始请求
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                Log.e("TAG", "error ", e);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                Log.e("TAG", response.body().string());
            }
        });

    }
}

紧接着就是布局文件了

layout_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".MainActivity">

    <ProgressBar
        android:id="@+id/upload_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="0"
        />

    <Button
        android:id="@+id/upload"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Upload"/>

    <ProgressBar
        android:id="@+id/download_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="0"
        />

    <Button
        android:id="@+id/download"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Download"/>

</LinearLayout>

另外别忘了给配置清单文件添加权限

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

还有一个就是添加依赖了

dependencies {
  compile ‘cn.edu.zafu:coreprogress:0.0.3‘
}

源代码地址:https://github.com/newcaoguo/CoreProgress.git

时间: 2024-08-10 15:03:55

Android使用OkHttp实现带进度的上传下载的相关文章

PHP+ajaxForm异步带进度条上传文件实例

在使用ajaxForm方法之前,首先需要安装form.js的插件,网上有: 一.首先说用法,ajaxForm可以接收0或1个参数,该参数可以是一个变量.一个对象或回调函数,这个对象主要有以下参数: var object= {                     url:url, //form提交数据的地址   type:type,   //form提交的方式(method:post/get)   target:target, //服务器返回的响应数据显示的元素(Id)号           

android使用HttpURLConnection实现带参数文件上传

文件上传是常见功能,然而android网上大多数的文件上传都使用httpclient,而且需要添加一个httpmine-jar,其实HttpURLConnection也可以实现文件上传,但是它在移动端有个弊端,就是不能上传大文件,所以这次说的方式,只能上传一些较小的文件. 文件上传,并且带上一些参数,这需要我们了解http请求的构造方式,也就是它的格式. HttpURLConnection需要我们自己构造请求头部,也就是我们要拼接出一个正确完整的请求. 下面来看一个典型的例子 POST /api

PHP+Ajax异步带进度条上传文件

前端引入文件 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script> <script src="

Android网络编程之使用HttpClient批量上传文件(二)AsyncTask+HttpClient并实现上传进度监听

请尊重他人的劳动成果,转载请注明出处: Android网络编程之使用HttpClient批量上传文件(二)AsyncTask+HttpClient并实现上传进度监听 运行效果图: 我曾在<Android网络编程之使用HttpClient批量上传文件>一文中介绍过如何通过HttpClient实现多文件上传和服务器的接收.在上一篇主要使用Handler+HttpClient的方式实现文件上传.这一篇将介绍使用AsyncTask+HttpClient实现文件上传并监听上传进度. 监控进度实现: 首先

Android开发中使用七牛云存储进行图片上传下载

Android开发中的图片存储本来就是比较耗时耗地的事情,而使用第三方的七牛云,便可以很好的解决这些后顾之忧,最近我也是在学习七牛的SDK,将使用过程在这记录下来,方便以后使用. 先说一下七牛云的存储原理,上面这幅图片是官方给出的原理图,表述当然比较清晰了.可以看出,要进行图片上传的话可以分为五大步: 1. 客户端用户登录到APP的账号系统里面: 2. 客户端上传文件之前,需要向业务服务器申请七牛的上传凭证,这个凭证由业务服务器使用七牛提供的服务端SDK生成: 3. 客户端使用七牛提供的客户端S

Android连接socket服务器上传下载多个文件

android连接socket服务器上传下载多个文件1.socket服务端SocketServer.java public class SocketServer { int port = 8888;// 端口号,必须与客户端一致 // 选择进行传输的文件(测试) String path = "C:\\Temp"; String filePath = "E:\\img.png"; Socket client; public static void main(Strin

Retrofit2文件上传下载及其进度显示

序 前面一篇文章介绍了Retrofit2的基本使用,这篇文章接着介绍使用Retrofit2实现文件上传和文件下载,以及上传下载过程中如何实现进度的显示. 文件上传 定义接口 1 2 3 @Multipart @POST("fileService") Call<User> uploadFile(@Part MultipartBody.Part file); 构造请求体上传 1 2 3 4 5 File file = new File(filePath); RequestBod

android+spring boot 选择,上传,下载文件

1 概述 前端android,上传与下载文件,使用OkHttp处理请求,后端使用spring boot+MVC,处理android发送来的上传与下载请求.这个其实不难,就是特别多奇奇怪怪的坑,因此,希望看到的,不要像笔者这样踩的那么痛苦了... 2 环境 win10 Spring Boot 2.2.2 RELEASE IDEA 2019.3.1 Android Studio 3.6RC1 Tomcat 9.0.30 3 android 3.1 准备工作 3.1.1 新建工程 这次用一个全新的例子

Android网络编程之使用HttpClient批量上传文件

请尊重他人的劳动成果,转载请注明出处:Android网络编程之使用HttpClient批量上传文件 我曾在<Android网络编程之使用HTTP访问网络资源>一文中介绍过HttpCient的使用,这里就不在累述了,感兴趣的朋友可以去看一下.在这里主要介绍如何通过HttpClient实现文件上传. 1.预备知识: 在HttpCient4.3之前上传文件主要使用MultipartEntity这个类,但现在这个类已经不在推荐使用了.随之替代它的类是MultipartEntityBuilder. 下面