2022-07-11 Android HttpURLConnection上传文件

背景

Android预览相机获取相机数据流转成图片文件通过HTTP上传到服务器

方案

在AsyncTask中使用HttpURLConnection将bitmap对象上传到服务器中

项目地址:https://gitee.com/premeditate/HF21029AR-OCR.git

package org.venus.ar.ocr.net;

import android.graphics.Bitmap;
import android.os.AsyncTask;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.venus.ar.ocr.MainActivity;
import org.venus.ar.ocr.utils.FileUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author Jxx     让世界看到我
 * @Create 2022/7/7 17:19
 * @Note 将摄像机获取到的图片上传到服务器进行OCR识别
 */
public class NetDetectTask extends AsyncTask<Bitmap, Boolean, List<Result>> {

    private String requestUrl;
    private MainActivity.OnDetectListener mDetectListener;
    private long start;

    public NetDetectTask(String url, MainActivity.OnDetectListener onDetectListener, long start) {
        this.requestUrl = url;
        this.mDetectListener = onDetectListener;
        this.start = start;
    }

    @Override
    protected List<Result> doInBackground(Bitmap... bitmaps) {
        if (bitmaps == null || bitmaps.length < 1 || bitmaps[0] == null) {
            return null;
        }

        //将bitmap转成file类型,用于上传
        //定义一个图片的文件名称
        String imageName = "ocr.jpg";
        File file = FileUtils.bitmap2File(bitmaps[0], imageName);

        if (file == null) {
            System.out.println("bitmap转file失败!");
            return null;
        }

        //创建参数列表
        Map<String, String> params = new HashMap<>();
        params.put("key", "value");

        //定义一个上传文件的边界线
        String BOUNDARY = "----WebKitFormBoundaryT1HoybnYeFOGFlBR";

        StringBuilder sb = new StringBuilder();
        for (String key : params.keySet()) {
            sb.append("--" + BOUNDARY + "\r\n");
            sb.append("Content-Disposition: form-data; name=\"" + key + "\"" + "\r\n");
            sb.append("\r\n");
            sb.append(params.get(key) + "\r\n");
        }

        //定义上传的文件的参数名称
        String fileParamName = "img";

        //添加请求头文件
        sb.append("--" + BOUNDARY + "\r\n");
        sb.append("Content-Disposition: form-data; name=\"" + fileParamName + "\"; filename=\"" + file.getName() + "\"" + "\r\n");
        // 如果服务器端有文件类型的校验,必须明确指定ContentType
        sb.append("Content-Type: image/jpeg" + "\r\n");
        sb.append("\r\n");

        HttpURLConnection conn = null;
        OutputStream out = null;
        InputStream in = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            byte[] headerInfo = sb.toString().getBytes("UTF-8");
            byte[] endInfo = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");

            //创建请求对象
            URL url = new URL(requestUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            // 设置传输内容的格式,以及长度
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            conn.setRequestProperty("Content-Length", String.valueOf(headerInfo.length + file.length() + endInfo.length));
            conn.setDoOutput(true);

            out = conn.getOutputStream();
            in = new FileInputStream(file);
            // 写入头部 (包含了普通的参数,以及文件的标示等)
            out.write(headerInfo);

            // 写入文件
            byte[] buf = new byte[1024 * 4];
            int len;
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            // 写入尾部
            out.write(endInfo);

            if (conn.getResponseCode() == 200) {
                //Read
                isr = new InputStreamReader(conn.getInputStream(), "UTF-8");
                br = new BufferedReader(isr);

                String line = null;
                StringBuilder sbr = new StringBuilder();
                while ((line = br.readLine()) != null) {
                    //System.out.println("Uploading............");
                    sbr.append(line);
                }

                String result = sbr.toString();
                //System.out.println("识别结果:" + result);
                try {
                    List<Result> data = new Gson().fromJson(result, new TypeToken<List<Result>>() {
                    }.getType());
                    return data;
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("返回结果转换错误");
                }
            } else {
                String responseMessage = conn.getResponseMessage();
                System.out.println("网络上传失败:" + conn.getResponseCode()+"-"+responseMessage);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (isr != null) {
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                conn.disconnect();
            }
        }

        return null;
    }

    @Override
    protected void onPostExecute(List<Result> result) {
        //super.onPostExecute(result);
        if (mDetectListener != null) {
            mDetectListener.result(result, start);
        }
    }
}
/**
     * bitmap转file
     * @param bitmap
     * @param fileName
     * @return
     */
    public static File bitmap2File(Bitmap bitmap, String fileName){
        String path = Environment.getExternalStorageDirectory() + "/bitmap2File";
        File dirFile = new File(path);
        if (!dirFile.exists()) {
            dirFile.mkdir();
        }
        File myCaptureFile = new File(path + fileName);
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            return myCaptureFile;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (bos!=null){
                try {
                    bos.flush();
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return  null;
    }

Android中bitmap不是File文件类型,在相机的数据流中获取到的bitmap对象,需要对图像进行上传,需要先将bitmap转成File对象。
HttpURLConnection做上传请求时,将File写到请求信息中,这里需要注意的是,上传文件需要添加一个边界符属性,否则服务器接收到这个文件有错误(以前用Java写HTTP接口时没有这样操作,这次使用的是Python做HTTP服务器,还没弄明白原理)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值