zoukankan      html  css  js  c++  java
  • android中的文件(图片)上传

    android中的文件(图片)上传其实没什么复杂的,主要是对 multipart/form-data 协议要有所了解。

    关于 multipart/form-data 协议,在 RFC文档中有详细的描述 RFC 2388 - Returning Values from Forms: multipart/form-data

    大家有兴趣的话可以去看看,这里有一篇非常好的文章进行了介绍:Http协议中的数据传送之多重表单提交--multipart/form-data

    那么在Android中如何实现呢?这里写了一个简单的工具类,供大家使用

    UploadUtil

    package com.atwal.util;
    
    import android.util.Log;
    
    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.net.URLEncoder;
    import java.util.Map;
    import java.util.UUID;
    
    /**
     * Created by atwal on 2016/3/11.
     */
    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 final String BOUNDARY = UUID.randomUUID().toString();  //边界标识随机生成
        private static final String PREFIX = "--";
        private static final String LINE_END = "
    ";
        private static final String CONTENT_TYPE = "multipart/form-data";   //内容类型
    
        /**
         * 上传文件
         * @param file 文件
         * @param RequestURL post地址
         * @param params 除文件外其他参数
         * @param uploadFieldName 上传文件key
         * @return
         */
        public static String uploadFile(File file, String RequestURL, Map<String, String> params, String uploadFieldName) {
            String result = null;
    
            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);
    
                DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
                StringBuffer sb = new StringBuffer();
                sb.append(getRequestData(params));
    
                if (file != null) {
                    sb.append(PREFIX);
                    sb.append(BOUNDARY);
                    sb.append(LINE_END);
                    sb.append("Content-Disposition: form-data; name="" + uploadFieldName + ""; 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());
                if (file != null) {
                    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();
                    dos.write(LINE_END.getBytes());
                    byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
                    dos.write(end_data);
                }
                dos.flush();
    
                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.i(TAG, "result : " + result);
                } else {
                    Log.e(TAG, "request error");
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }
    
        /**
         * 对post参数进行编码处理
         * @param params post参数
         * @return
         */
        private static StringBuffer getRequestData(Map<String, String> params) {
            StringBuffer stringBuffer = new StringBuffer();
            try {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    stringBuffer.append(PREFIX);
                    stringBuffer.append(BOUNDARY);
                    stringBuffer.append(LINE_END);
                    stringBuffer.append("Content-Disposition: form-data; name="" + entry.getKey() + """ + LINE_END);
                    stringBuffer.append(LINE_END);
                    stringBuffer.append(URLEncoder.encode(entry.getValue(), CHARSET));
                    stringBuffer.append(LINE_END);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return stringBuffer;
        }
    }
    
    

    代码比较简单,就不细说了,主要就是把参数及文件按协议进行拼接。

    注:本类代码参考了android上传文件到服务器 一文,做了优化修改

    调用

    调用代码比较简单,这里需要注意的是,文件上传是一个网络操作,要另开线程处理。另外要给应用网络和SD卡读写权限。

    String requestURL = "服务器地址";
    String picPath = "图片地址";
    File file = new File(picPath);
    Log.i("upload", "file exists:" + file.exists());
    if (file.exists()) {
        Map<String, String> params = new HashMap<>();
        params.put("id", "1");
        //...如果有其他参数添加到这里
        String request = UploadUtil.uploadFile(file, requestURL, params, "image");
        Log.i("upload", request);
    }
    

    当然,此工具类对异常信息并未处理,大家可根据自己的情况进行优化。

  • 相关阅读:
    三大主流负载均衡软件对比(LVS+Nginx+HAproxy)
    nginx 提示the "ssl" directive is deprecated, use the "listen ... ssl" directive instead
    centos安装nginx并配置SSL证书
    hadoop创建目录文件失败
    The server time zone value 'EDT' is unrecognized or represents more than one time zone.
    脚本启动SpringBoot(jar)
    centos做免密登录
    数据库远程连接配置
    Bash 快捷键
    TCP三次握手四次断开
  • 原文地址:https://www.cnblogs.com/lurenjiashuo/p/android-upload-file.html
Copyright © 2011-2022 走看看