Retrofit图片上传

本篇连接上一篇的选择图片  至于retrofit的搭建我就不写了吧 只贴需要的代码 不然代码量太大了

获取图片然后判断类型 压缩 判断大小 上传 我感觉我写的注释还是很详细的 

本篇的整个格式是retrofit+rxjava的 

showLoading();这个是写在base的一个加载框 大家可以忽略     

 private void initSetPhone() {
        if (photoPath != null) {
            //判断是什么类型的图片
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds =true;
            BitmapFactory.decodeFile(photoPath,options);
            type = options.outMimeType;
            Log.d("image type -> ", type);
            if (TextUtils.isEmpty(type)) {
                type = "未能识别的图片";
            } else {
                type = type.substring(6, type.length());
            }
            Log.d("image type -> ", type);
            //筛选需要的类型
            if (type.equals("jpeg") || type.equals("png")) {
                File file = new File(photoPath);
                //鲁班图片压缩
                Luban.with(this)
                        .load(file)                                   // 传人要压缩的图片列表
                        .ignoreBy(100)                                  // 忽略不压缩图片的大小
                        .setTargetDir(getPath())// 设置压缩后文件存储位置
                        .setCompressListener(new OnCompressListener() { //设置回调
                            @Override
                            public void onStart() {
                                // TODO 压缩开始前调用,可以在方法内启动 loading UI
//                                LogUtil.e("lin","压缩开始");
                            }

                            @Override
                            public void onSuccess(File file) {
                                // TODO 压缩成功后调用,返回压缩后的图片文件
                                Log.e("Response", "showImages3: " + file);
                                //判断压缩后的图片大小
                                String path = file.getPath();
                                double filesSize = FileSizeUtil.getFileOrFilesSize(path, 3);
                                if (filesSize > 3) {
                                    showToast("图片的文件大小需要小于3M");
                                    return;
                                }
                                //上传压缩后的头像
                                presenter.sendPhotoMsg(file, personalId + "", type);
                                showLoading();
                            }

                            @Override
                            public void onError(Throwable e) {
                                // TODO 当压缩过程出现问题时调用
                                LogUtil.e("lin","压缩过程出现问题");
                            }
                        }).launch();    //启动压缩
            } else {
                showToast("图片的格式需要是jpg/png格式");
                LogUtil.e("lin", "图片的格式需要是jpg/png格式");
            }
        }
    }

    private String getPath() {
        String path = Environment.getExternalStorageDirectory() + "/Luban/image/";
        File file = new File(path);
        if (file.mkdirs()) {
            return path;
        }
        return path;
    }

这里用到一个判断大小的工具类 但是都压缩了 我感觉是没什么用了

package com.iimpath.www.util;

import java.io.File;
import java.io.FileInputStream;
import java.text.DecimalFormat;

/**
 * Created by admin on 2017/2/14.
 */

public class FileSizeUtil {
    private static final String TAG=FileSizeUtil.class.getSimpleName();

    public static final int SIZETYPE_B = 1;//获取文件大小单位为B的double值
    public static final int SIZETYPE_KB = 2;//获取文件大小单位为KB的double值
    public static final int SIZETYPE_MB = 3;//获取文件大小单位为MB的double值
    public static final int SIZETYPE_GB = 4;//获取文件大小单位为GB的double值

    /**
     * 获取文件指定文件的指定单位的大小
     *
     * @param filePath 文件路径
     * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB
     * @return double值的大小
     */
    public static double getFileOrFilesSize(String filePath, int sizeType) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
   //         LogUtil.E(TAG,"获取文件大小失败!");
        }
        return FormetFileSize(blockSize, sizeType);
    }

    /**
     * 调用此方法自动计算指定文件或指定文件夹的大小
     *
     * @param filePath 文件路径
     * @return 计算好的带B、KB、MB、GB的字符串
     */
    public static String getAutoFileOrFilesSize(String filePath) {
        File file = new File(filePath);
        long blockSize = 0;
        try {
            if (file.isDirectory()) {
                blockSize = getFileSizes(file);
            } else {
                blockSize = getFileSize(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
     //       LogUtil.E(TAG,"获取文件大小失败!");
        }
        return FormetFileSize(blockSize);
    }

    /**
     * 获取指定文件大小
     *
     * @param file
     * @return
     * @throws Exception
     */
    private static long getFileSize(File file) throws Exception {
        long size = 0;
        if (file.exists()) {
            FileInputStream fis = null;
            fis = new FileInputStream(file);
            size = fis.available();
        } else {
            file.createNewFile();
//            Log.E(TAG,"获取文件大小不存在!");
        }
        return size;
    }

    /**
     * 获取指定文件夹
     *
     * @param f
     * @return
     * @throws Exception
     */
    private static long getFileSizes(File f) throws Exception {
        long size = 0;
        File flist[] = f.listFiles();
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSizes(flist[i]);
            } else {
                size = size + getFileSize(flist[i]);
            }
        }
        return size;
    }

    /**
     * 转换文件大小
     *
     * @param fileS
     * @return
     */
    private static String FormetFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * 转换文件大小,指定转换的类型
     *
     * @param fileS
     * @param sizeType
     * @return
     */
    private static double FormetFileSize(long fileS, int sizeType) {
        DecimalFormat df = new DecimalFormat("#.00");
        double fileSizeLong = 0;
        switch (sizeType) {
            case SIZETYPE_B:
                fileSizeLong = Double.valueOf(df.format((double) fileS));
                break;
            case SIZETYPE_KB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
                break;
            case SIZETYPE_MB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
                break;
            case SIZETYPE_GB:
                fileSizeLong = Double.valueOf(df.format((double) fileS / 1073741824));
                break;
            default:
                break;
        }
        return fileSizeLong;
    }
}

接下来详细说下上传操作

file 压缩后的文件 
personalId 后台要的用户id
type 这个倒是没要 主要是后台加了一个类型判断 这个是保存当前图片类型的 
//上传压缩后的头像
                                presenter.sendPhotoMsg(file, personalId + "", type);

这是后台的接口

Retrofit图片上传_第1张图片

这是我的ApiService

 //上传头像
    @Multipart
    @POST(URL.SaveThePictureMessage)
    Observable saveThePictureMsg(@Part List partList);

这是p层

"multipart/form-data" 后台没限制可以用这个 都可以传 限制的话就。。传对应的 对了我们后台是php的 我不太懂这个

 //上传头像
    @Override
    public void sendPhotoMsg(File file_name, String id,String type) {

        //1.创建MultipartBody.Builder对象
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);

        //2.获取图片,创建请求体
//        RequestBody body=RequestBody.create(MediaType.parse("multipart/form-data"),file_name);//表单类型
        RequestBody body=RequestBody.create(MediaType.parse("image/"+type),file_name);//表单类型

        //3.调用MultipartBody.Builder的addFormDataPart()方法添加表单数据
        builder.addFormDataPart("file_name",file_name.getName(),body); //添加图片数据,body创建的请求体
        builder.addFormDataPart("id", id);//传入服务器需要的key,和相应value值

        //4.创建List 集合,
        //  调用MultipartBody.Builder的build()方法会返回一个新创建的MultipartBody
        //  再调用MultipartBody的parts()方法返回MultipartBody.Part集合
        List parts = builder.build().parts();

        //5.最后进行HTTP请求,传入parts即可
        ApiService apiService = RetrofitUtils.getInstence().getAService();
        apiService.saveThePictureMsg(parts)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1() {
                    @Override
                    public void call(SaveThePictureBean saveThePictureBean) {
                        view.showPhotoMsg(saveThePictureBean);
                    }
                }, new Action1() {
                    @Override
                    public void call(Throwable throwable) {
                        view.throwable(throwable.toString());
                    }
                });

    }

熟悉retrofit的应该都能看懂吧。。。

dismissLoading(); base里面的取消加载框的方法 可以忽略

/*
    * 修改头像的回调
    * */
    @Override
    public void showPhotoMsg(SaveThePictureBean saveThePictureBean) {
        dismissLoading();
        LogUtil.e("lin", saveThePictureBean.getCode() + saveThePictureBean.getMsg());
        if (saveThePictureBean.getCode().equals("200")) {
          
        } else {
            showToast("修改失败");
        }
    }

当时上传图片时我可是扣了很久的  亲测可用 如果不可用 那就是后台设置不同的问题了  一脸懵的百度了一堆 试一个不行就换 终于功夫不负有心人 我成功了 嘿嘿 经验+1

如果上传失败 就让后台把你传上去的东西全返回回来 对比下就知道了 当初后台该类型限制可是坑了我一把

你可能感兴趣的:(Retrofit图片上传)