本篇连接上一篇的选择图片 至于retrofit的搭建我就不写了吧 只贴需要的代码 不然代码量太大了
获取图片然后判断类型 压缩 判断大小 上传 我感觉我写的注释还是很详细的
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);
这是后台的接口
这是我的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
如果上传失败 就让后台把你传上去的东西全返回回来 对比下就知道了 当初后台该类型限制可是坑了我一把