package com.forfan.bigbang.network; /** * Created by wangyan-pd on 2017/1/17. */ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; import android.util.Log; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Map; import java.util.UUID; /** * 上传文件到服务器类 * 用于上传到图床,被retrofit坑惨了 */ public class UploadUtil { private static final String TAG = "uploadFile"; private static final int TIME_OUT = 10 * 1000; // 超时时间 private static final String CHARSET = "utf-8"; // 设置编码 private static byte[] getimage(File srcPath) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); //开始读入图片,此时把options.inJustDecodeBounds 设回true了 newOpts.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(srcPath.getAbsolutePath(), newOpts);//此时返回bm为空 newOpts.inJustDecodeBounds = false; int w = newOpts.outWidth; int h = newOpts.outHeight; //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为 float hh = 800f;//这里设置高度为800f float ww = 480f;//这里设置宽度为480f //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 int be = 1;//be=1表示不缩放 if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放 be = (int) (newOpts.outWidth / ww); } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放 be = (int) (newOpts.outHeight / hh); } if (be <= 0) be = 1; newOpts.inSampleSize = be;//设置缩放比例 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 bitmap = BitmapFactory.decodeFile(srcPath.getAbsolutePath(), newOpts); return compressImage(bitmap);//压缩好比例大小后再进行质量压缩 } private static byte[] compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩 baos.reset();//重置baos即清空baos options -= 10;//每次都减少10 image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 } return baos.toByteArray(); // ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 // Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 // return bitmap; } /** * Android上传文件到服务端 * * @param file 需要上传的文件 * @return 返回响应的内容 */ public static String uploadFile(File file) { String RequestURL = "https://sm.ms/api/upload"; String result = null; String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成 String PREFIX = "--", LINE_END = "\r\n"; String CONTENT_TYPE = "multipart/form-data"; // 内容类型 try { URL url = new URL(RequestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(TIME_OUT); conn.setConnectTimeout(TIME_OUT); conn.setDoInput(true); // 允许输入流 conn.setDoOutput(true); // 允许输出流 conn.setUseCaches(false); // 不允许使用缓存 conn.setRequestMethod("POST"); // 请求方式 conn.setRequestProperty("Charset", CHARSET); // 设置编码 conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); if (Build.VERSION.SDK != null && Build.VERSION.SDK_INT > 13) { conn.setRequestProperty("Connection", "close"); } if (file != null) { /** * 当文件不为空,把文件包装并且上传 */ DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); StringBuffer sb = new StringBuffer(); // // sb.append(PREFIX); // sb.append(BOUNDARY); // sb.append(LINE_END); // sb.append("Content-Disposition: form-data; name=\"Token\"" + LINE_END); // sb.append("c601d5d96c7438b7a6801f9715820bc6e561db4b:eDYtR2NnVlVpWEdRX2pDM1hJV2lwTjAwSndJPQ==:eyJkZWFkbGluZSI6MTQ0Njk3MjkxOSwiYWN0aW9uIjoiZ2V0IiwidWlkIjoiNTIzMDYwIiwiYWlkIjoiMTE1MTg3NiIs"); // sb.append(LINE_END); sb.append(PREFIX); sb.append(BOUNDARY); sb.append(LINE_END); /** * 这里重点注意: name里面的值为服务端需要key 只有这个key 才可以得到对应的文件 * filename是文件的名字,包含后缀名的 比如:abc.png */ sb.append("Content-Disposition: form-data; name=\"smfile\"; filename=\"" + file.getName() + "\"" + LINE_END); // sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END); sb.append("Content-Type: image/*" + LINE_END); sb.append(LINE_END); Log.e("shang", sb.toString()); dos.write(sb.toString().getBytes()); // InputStream is = new FileInputStream(file); // byte[] bytes = new byte[1024]; // int len = 0; // while ((len = is.read(bytes)) != -1) { // dos.write(bytes, 0, len); // } // is.close(); byte[] bytes = getimage(file); dos.write(bytes, 0, bytes.length); dos.write(LINE_END.getBytes()); byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes(); dos.write(end_data); dos.flush(); /** * 获取响应码 200=成功 当响应成功,获取响应的流 */ int res = conn.getResponseCode(); Log.e(TAG, "response code:" + res); // if(res==200) // { Log.e(TAG, "request success"); InputStream input = conn.getInputStream(); StringBuffer sb1 = new StringBuffer(); int ss; while ((ss = input.read()) != -1) { sb1.append((char) ss); } result = sb1.toString(); Log.e(TAG, "result : " + result); // } // else{ // Log.e(TAG, "request error"); // } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } /** * 通过拼接的方式构造请求内容,实现参数传输以及文件传输 * * @param url Service net address * @param params text content * @param files pictures * @return String result of Service response * @throws IOException */ public static String post(String url, Map<String, String> params, Map<String, File> files) throws IOException { String BOUNDARY = UUID.randomUUID().toString(); String PREFIX = "--", LINEND = "\r\n"; String MULTIPART_FROM_DATA = "multipart/form-data"; String CHARSET = "UTF-8"; URL uri = new URL(url); HttpURLConnection conn = (HttpURLConnection) uri.openConnection(); conn.setReadTimeout(10 * 1000); // 缓存的最长时间 conn.setDoInput(true);// 允许输入 conn.setDoOutput(true);// 允许输出 conn.setUseCaches(false); // 不允许使用缓存 conn.setRequestMethod("POST"); conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Charsert", "UTF-8"); conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY); // 首先组拼文本类型的参数 StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> entry : params.entrySet()) { sb.append(PREFIX); sb.append(BOUNDARY); sb.append(LINEND); sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND); sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND); sb.append("Content-Transfer-Encoding: 8bit" + LINEND); sb.append(LINEND); sb.append(entry.getValue()); sb.append(LINEND); } DataOutputStream outStream = new DataOutputStream(conn.getOutputStream()); outStream.write(sb.toString().getBytes()); // 发送文件数据 if (files != null) for (Map.Entry<String, File> file : files.entrySet()) { StringBuilder sb1 = new StringBuilder(); sb1.append(PREFIX); sb1.append(BOUNDARY); sb1.append(LINEND); sb1.append("Content-Disposition: form-data; name=\"uploadfile\"; filename=\"" + file.getValue().getName() + "\"" + LINEND); sb1.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINEND); sb1.append(LINEND); outStream.write(sb1.toString().getBytes()); InputStream is = new FileInputStream(file.getValue()); byte[] buffer = new byte[1024]; int len = 0; while ((len = is.read(buffer)) != -1) { outStream.write(buffer, 0, len); } is.close(); outStream.write(LINEND.getBytes()); } // 请求结束标志 byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes(); outStream.write(end_data); outStream.flush(); // 得到响应码 int res = conn.getResponseCode(); InputStream in = conn.getInputStream(); StringBuilder sb2 = new StringBuilder(); if (res == 200) { int ch; while ((ch = in.read()) != -1) { sb2.append((char) ch); } } outStream.close(); conn.disconnect(); return sb2.toString(); } }