头像上传,打开相册 —— 图片压缩——上传成功 (附三星手机适配图片旋转问题)

   你还在一模块一模块的做上传头像吗,先搜索打开相册的代码,适配、测试,再找压缩图片方法,测试。再找上传的方法,再测试。小弟不喜欢麻烦,自己写了一个总结性的博客,还望大家多多指出不足和缺点。能帮到大家是最好。



一. 通过隐式意图打开相册


//打开相册

Intent intent=new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 80);
intent.putExtra("outputY", 80);
intent.putExtra("return-data", true);
settingActivity.startActivityForResult(intent, 0);



二. 接受结果 压缩并上传


//返回来url 并进行上传处理
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    System.out.println(resultCode);
    if (resultCode == -1) {
        uri = data.getData();

        final String url = "你的上传地址";

        //质量压缩
        //final String pathDiv = getPathDiv(uri);
        // Bitmap  bitmap = decodeUriAsBitmap(uri);
        // file = compressImage(bitmap);

        //大小压缩+质量压缩
        file = compression(pathDiv);


        //map里携带的参数是利用HttpURLConnection上传头像时所需的参数
        final HashMap map = new HashMap();
        map.put("userid", "25");

        //子线程上传
        new Thread(new Runnable() {
            @Override
            public void run() {
                upload(url, file, map, new FileUploadListener() {
                    private JSONObject err;
                    private HiDataException error;

                    @Override
                    public void onProgress(long pro, double precent) {

                    }

                    @Override
                    public void onFinish(final int code, String res, Map> headers) {

                        //解析后台数据 (因后台json格式是json串嵌套的json串数据,所以手写的解析而没用json)

                        try {
                            JSONTokener parser = new JSONTokener(res);
                            JSONObject json = null;
                            json = (JSONObject) parser.nextValue();
                            err = json.optJSONObject("ErrorResponse");
                            if (err != null) {
                                error = new HiDataException();

                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {

                                        if (code == 200 && !"".equals(err.getString("ErrorMsg"))) {

                                            showToast("完成上传!");

                                        } else {
                                            showToast("上传失败!");

                                        }

                                    }
                                });

                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }
                });

            }
        }).start();

    }
}



三.  上边代码所用到的工具类


/**
 * 图片按比例大小压缩方法 
 *
 * @param srcPath (根据路径获取图片并压缩)
 * @return
 */
public static File compression(String srcPath) {

    BitmapFactory.Options newOpts = new BitmapFactory.Options();
    // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
    newOpts.inJustDecodeBounds = true;
    Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空

    newOpts.inJustDecodeBounds = false;
    int w = newOpts.outWidth;
    int h = newOpts.outHeight;
    float hh = 200f;
    float ww = 200f;
    int be = 1;//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;// 设置缩放比例
    bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
    return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
}


  /**
     * 压缩图片(质量压缩)
     * @param bitmap
     */
    public static File compressImage(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 200) {  //循环判断如果压缩后图片是否大于200kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            options -= 10;//每次都减少10
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
            long length = baos.toByteArray().length;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date(System.currentTimeMillis());
        String filename = format.format(date);
        File file = new File(Environment.getExternalStorageDirectory(),filename+".png");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            try {
                fos.write(baos.toByteArray());
                fos.flush();
                fos.close();
            } catch (IOException e) {
//                BAFLogger.e(TAG,e.getMessage());
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
//            BAFLogger.e(TAG,e.getMessage());
            e.printStackTrace();
        }
        recycleBitmap(bitmap);
        Log.e("","压缩之后的文件大小"+file.length());
        return file;
    }



/**
 * 释放
 * @param bitmaps
 */
public static void recycleBitmap(Bitmap... bitmaps) {
    if (bitmaps==null) {
        return;
    }
    for (Bitmap bm : bitmaps) {
        if (null != bm && !bm.isRecycled()) {
            bm.recycle();
        }
    }
}




/**
 * 上传图片方法
 * @param host
 * @param file
 * @param params
 * @param listener
 */

public static void upload(String host,File file,Map params,FileUploadListener listener){
    String BOUNDARY = UUID.randomUUID().toString(); //边界标识 随机生成 String PREFIX = "--" , LINE_END = "\r\n";
    String CONTENT_TYPE = "multipart/form-data"; //内容类型
    try {
        URL url = new URL(host);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(TIME_OUT);
        conn.setConnectTimeout(TIME_OUT);
        conn.setRequestMethod("POST"); //请求方式
        conn.setRequestProperty("Charset", CHARSET);//设置编码
        conn.setRequestProperty("connection", "keep-alive");
        conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
        conn.setDoInput(true); //允许输入流
        conn.setDoOutput(true); //允许输出流
        conn.setUseCaches(false); //不允许使用缓存
        if(file!=null) {
            /** * 当文件不为空,把文件包装并且上传 */
            OutputStream outputSteam=conn.getOutputStream();
            DataOutputStream dos = new DataOutputStream(outputSteam);
            StringBuffer sb = new StringBuffer();
            sb.append(LINE_END);
            if(params!=null){//根据格式,开始拼接文本参数
                for(Map.Entry entry:params.entrySet()){
                    sb.append(PREFIX).append(BOUNDARY).append(LINE_END);//分界符
                    sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINE_END);
                    sb.append("Content-Type: text/plain; charset=" + CHARSET + LINE_END);
                    sb.append("Content-Transfer-Encoding: 8bit" + LINE_END);
                    sb.append(LINE_END);
                    sb.append(entry.getValue());
                    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=\"uploadedPicture\"; filename=\""+file.getName()+"\""+LINE_END);
            sb.append("Content-Type: application/octet-stream; charset="+CHARSET+LINE_END);
            sb.append(LINE_END);
            //写入文件数据
            dos.write(sb.toString().getBytes());
            InputStream is = new FileInputStream(file);
            byte[] bytes = new byte[1024];
            long totalbytes = file.length();
            long curbytes = 0;
            Log.i("cky","total="+totalbytes);
            int len = 0;
            while((len=is.read(bytes))!=-1){
                curbytes += len;
                dos.write(bytes, 0, len);
                listener.onProgress(curbytes,1.0d*curbytes/totalbytes);
            }
            is.close();
            dos.write(LINE_END.getBytes());
            byte[] end_data = (PREFIX+BOUNDARY+PREFIX+LINE_END).getBytes();
            dos.write(end_data);
            dos.flush();
            /**
             * 获取响应码 200=成功
             * 当响应成功,获取响应的流
             */
            int code = conn.getResponseCode();
            sb.setLength(0);
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while((line=br.readLine())!=null){
                sb.append(line);
            }
            listener.onFinish(code,sb.toString(),conn.getHeaderFields());
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public interface FileUploadListener{
    public void onProgress(long pro,double precent);
    public void onFinish(int code,String res,Map> headers);
}


你可能感兴趣的:(自定义)