okhttp 基本用法二 下载/上传

下面所写内容都有源码都能直接使用可供下载,使用图片下载、上传都是真实有效的地址,可直接使用:

项目下载地址:https://github.com/cmyeyi/NetFramework

okhttp依赖库导入参考上一篇:android 网络3 okhttp(1) get/post基本用法

一个很好的图片压缩网站:https://tinypng.com/    这里上传图片便依赖此网站,可能需要vpn

1、异步文件下载

文件的下载不需要我们制定是什么访问类型,具体实践操作如下,原理就是从网络上获取所需要下载的文件的流,然后通过IO操作存入本地,下面将要操作从网络上下载一张图片,让后保存在根目录:

private void download() {

    String imageUrl = "https://picjumbo.com/wp-content/uploads/abstract-free-photo-1570x1047.jpg";
    Request request = new Request.Builder().url(imageUrl).build();
    OkHttpClient okHttpClient = new OkHttpClient();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG, e.getLocalizedMessage());
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.e(TAG, response.message());
            InputStream inputStream = response.body().byteStream();
            FileOutputStream fileOutputStream = null;
            String filePath = "";

            try {
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    Log.d(TAG, "get file path#1#");
                    filePath = Environment.getExternalStorageDirectory().getAbsolutePath();
                } else {
                    filePath = getActivity().getFilesDir().getAbsolutePath();
                    Log.d(TAG, "get file path#2#");
                }
                Log.d(TAG, "filepath = " + filePath);
                File file = new File(filePath, "abstract-free-photo-1570x1047.jpg");
                if (!file.exists()) {
                    fileOutputStream = new FileOutputStream(file);
                    byte[] buffer = new byte[1024];
                    int length = 0;
                    while ((length = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, length);
                    }
                    fileOutputStream.flush();
                }
            } catch (IOException e) {
                Log.e(TAG, "IOException");
                e.printStackTrace();
            }

        }
    });

}

2、异步上传文件

上传文件本质上也是一种post请求

比如我们将要将手机根目录下的一张图片上传到图片压缩网站:https://tinypng.com/web/shrink

public final static MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/png");
public final static String UPLOAD_URL = "https://tinypng.com/web/shrink";
public final static String DEFAULT_PATH = "/storage/emulated/0";


/**
 * MediaType是什么
 * MediaType在网络协议的消息头里面叫做Content-Type
 * 使用两部分的标识符来确定一个类型
 * 所以我们用的时候其实就是为了表明我们传的东西是什么类型
 * 比如
 * application/json:JSON格式的数据,在RFC 4627中定义
 * application/javascript:JavaScript,在RFC 4329中定义但是不被IE8以及之前的版本支持
 * audio/mp4:MP4音频
 * audio/mpeg:MP3 或者MPEG音频,在RFC 3003中定义
 * image/jpeg:JPEG 和JFIF格式,在RFC 2045 和 RFC 2046中定义
 * image/png:png格式,在 RFC 2083中定义
 * text/html:HTML格式,在RFC 2854中定义
 * text/javascript :JavaScript在已经废弃的RFC 4329中定义,现在推荐使用“application/javascript”。然而“text/javascript”允许在HTML 4 和5 中使用。并且与“application/javascript”不同,它是可以跨浏览器支持的
 *
 * @param parent 被上传文件的父路径
 * @param child  被上传文件名
 */
private void upload(String parent, String child) {
    Log.d(TAG, "#begin upload#");
    File file = new File(parent, child);
    Request request = new Request.Builder().url(UPLOAD_URL).post(RequestBody.create(MEDIA_TYPE_IMAGE, file)).build();
    OkHttpClient okHttpClient = new OkHttpClient();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG,"failure:" + e.getLocalizedMessage());
            Log.d(TAG,"#upload over#");
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.d(TAG,"response message|" + response.message());
            if(response.isSuccessful()){
                Log.d(TAG,"upload success,response|" + response.body().string());
            } else {
                Log.d(TAG,"upload failure,response|" + response.message());
            }
            Log.d(TAG,"#upload over#");
        }
    });


}

private void uploadImage() {
    String imageName = "abstract-free-photo-1570x1047.jpg";
    String imagePath = DEFAULT_PATH;
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        imagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
    } else {
        return;
    }

    upload(imagePath, imageName);
}

上传完毕之后返回结果如下:

{"input":{"size":198123,"type":"image/jpeg"},"output":{"size":161269,"type":"image/jpeg","width":1570,"height":1047,"ratio":0.814,"url":"https://tinypng.com/web/output/50hyahgdxxnw20w7z854qqqr3tyxav8u"}}

https://tinypng.com/web/output/50hyahgdxxnw20w7z854qqqr3tyxav8u 是处理完毕图片后,新图片的下载地址

3、异步以MultipartBody形式上传文件

其实也就是javaweb上的表单提交等,一次性上传多组数据,包括文件、图片等

这里给一个简单的例子,当然,还是用的上面的url上传地址,肯定是无法通过的,这里仅是说明一下这种通过okhttp3上传服务器的方式,以后再详细说明:

private void uploadMultiFile(String parent, String child) {
    Log.d(TAG, "#begin upload multi#");
    File file = new File(parent, child);

    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("title", "good image")
            .addFormDataPart("image", child, RequestBody.create(MEDIA_TYPE_IMAGE, file))
            .build();

    Request request = new Request.Builder()
            .url(UPLOAD_URL)
            .post(requestBody)
            .build();

    OkHttpClient okHttpClient = new OkHttpClient();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG, "multi failure:" + e.getLocalizedMessage());
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.d(TAG, "multi response message|" + response.message());
            if (response.isSuccessful()) {
                Log.d(TAG, "upload multi success,response|" + response.body().string());
            } else {
                Log.d(TAG, "upload multi failure,response|" + response.message());
            }
        }
    });

}

private void doUploadMultiFile() {
    String imageName = "abstract-free-photo-1570x1047.jpg";
    String imagePath = DEFAULT_PATH;
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        imagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
    } else {
        return;
    }

    uploadMultiFile(imagePath, imageName);
}

猜你喜欢

转载自blog.csdn.net/weixin_36709064/article/details/82153385