基于标准的http来实现Android多文件上传详解手机开发

实现多文件的上传,基于标准的http来实现。

  1. 多文件上传MyUploader类的实现:
/** 
 *  
 * 同步上传多个文件 
 * 基于标准的http实现,需要在非UI线程中调用,以免阻塞UI。 
 * 
 */ 
public class MyUploader { 
    private static final String TAG = "MyUploader"; 
 
    // ////////////////////同步上传多个文件///////// 
        /** 
         * 同步上传File 
         *  
         * @param Url 
         * @param fullFileName 
         *            : 全路径,ex. /sdcard/f/yh.jpg 
         * @param fileName 
         *            : file name, ex. yh.jpg 
         * @return 服务器的响应结果(字符串形式) 
         */ 
        public String MyUploadMultiFileSync(String Url, 
                List<String> fileList, Map<String, String> params) { 
            String reulstCode = ""; 
            String end = "/r/n"; 
            String twoHyphens = "--"; 
            String boundary = "--------boundary"; 
 
            try { 
                URL url = new URL(actionUrl); 
                HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
                // 允许Input、Output,不使用Cache 
                con.setDoInput(true); 
                con.setDoOutput(true); 
                con.setUseCaches(false); 
                // 设置传送的method=POST 
                con.setRequestMethod("POST"); 
                // setRequestProperty 
                con.setRequestProperty("Connection", "Keep-Alive"); 
                con.setRequestProperty("Charset", "UTF-8"); 
                // con.setRequestProperty("Content-Type", 
                // "application/x-www-form-urlencoded"); 
                con.setRequestProperty("Content-Type", 
                        "multipart/form-data;boundary=" + boundary); 
 
                StringBuffer s = new StringBuffer(); 
                // 设置DataOutputStream 
                DataOutputStream dos = new DataOutputStream(con.getOutputStream()); 
 
                for (int i = 0; i < fileList.size(); i++) { 
 
                    String filePath = fileList.get(i); 
 
                    int endFileIndex = filePath.lastIndexOf("/"); 
                    String fileName = filePath.substring(endFileIndex + 1); 
                    Log.i(TAG, "filename= " + fileName); 
                    // set 头部 
                    StringBuilder sb = new StringBuilder(); 
 
                    sb.append(twoHyphens); 
                    sb.append(boundary); 
                    sb.append(end); 
                    sb.append("Content-Disposition: form-data; "); 
                    sb.append("name=" + "/"" + "upload_file" +i + "/""); 
                    sb.append(";filename="); 
                    sb.append("/"" + fileName + "/""); 
                    sb.append(end); 
 
                    sb.append("Content-Type: "); 
                    sb.append("image/jpeg"); 
                    sb.append(end); 
                    sb.append(end); 
 
                    // 1. write sb 
                    dos.writeBytes(sb.toString()); 
 
                    // 取得文件的FileInputStream 
                    FileInputStream fis = new FileInputStream(filePath); 
                    // 设置每次写入1024bytes 
                    int bufferSize = 1024; 
                    byte[] buffer = new byte[bufferSize]; 
 
                    int length = -1; 
                    // 从文件读取数据至缓冲区 
                    while ((length = fis.read(buffer)) != -1) { 
                        dos.write(buffer, 0, length); 
                    } 
                    dos.writeBytes(end); 
                    fis.close(); 
 
                    dos.writeBytes(end); 
                    dos.writeBytes(end); 
 
                    //dos.writeBytes(end); 
                    //dos.flush(); 
                    // close streams 
                    //fis.close(); 
                } 
 
                // set 尾部 
                StringBuilder sb2 = new StringBuilder(); 
 
                if (params != null && !params.isEmpty()) { 
                    for (String key : params.keySet()) { 
                        String value = params.get(key); 
                        sb2.append(twoHyphens); 
                        sb2.append(boundary); 
                        sb2.append(end); 
                        sb2.append("Content-Disposition: form-data; "); 
                        sb2.append("name=" + "/""); 
                        sb2.append(key + "/""); 
                        sb2.append(end); 
                        sb2.append(end); 
                        sb2.append(value); 
                        sb2.append(end); 
                    } 
                } 
                sb2.append(twoHyphens + boundary + end); 
                dos.writeBytes(sb2.toString()); 
                dos.flush(); 
                Log.i(TAG, "sb2:" + sb2.toString()); 
 
                // 取得Response内容 
                InputStream is = con.getInputStream(); 
                int ch; 
                StringBuffer b = new StringBuffer(); 
                while ((ch = is.read()) != -1) { 
                    b.append((char) ch); 
                } 
                reulstCode = b.toString().trim(); 
                // 关闭 
                dos.close(); 
            } catch (IOException e) { 
                Log.i(TAG, "IOException: " + e); 
                e.printStackTrace(); 
            } 
 
            return reulstCode; 
        } 
}

2. 调用方法:

由于MyUploader的MyUploadMultiFileSync本身是同步的函数请求,所以,这个函数需要在非UI线程中执行。本例采用Thread+Handler的方式来进行说明。
下面是activity的主要代码,功能是将cache目录中的的jpg文件上传到指定的服务器:

public void uploadThreadTest() { 
        new Thread(new Runnable() { 
            @Override 
            public void run() { 
 
                try { 
                    upload(); 
                } catch (Exception e) { 
                    e.printStackTrace(); 
                } 
            } 
 
        }).start(); 
 
    } 
 
    private void upload() { 
        String url = "https://httpbin.org/post"; 
        List<String> fileList = getCacheFiles(); 
 
        if (fileList == null) { 
            myHandler.sendEmptyMessage(-1); 
        }else { 
            MyUploader myUpload = new MyUploader(); 
            //同步请求,直接返回结果,根据结果来判断是否成功。 
            String reulstCode = myUpload.MyUploadMultiFileSync(url, fileList, null); 
            Log.i(TAG, "upload reulstCode: " + reulstCode); 
            myHandler.sendEmptyMessage(0); 
 
        } 
    } 
 
    private List<String> getCacheFiles() { 
        List<String> fileList = new ArrayList<String>(); 
        File catchPath = mContext.getCacheDir(); 
 
        if (catchPath!=null && catchPath.isDirectory()) { 
 
            File[] files = catchPath.listFiles(); 
            if (files == null || files.length<1) { 
                return null; 
            } 
            for (int i = 0; i < files.length; i++) { 
                if (files[i].isFile() && files[i].getAbsolutePath().endsWith(".jpg")) { 
                    fileList.add(files[i].getAbsolutePath()); 
                } 
 
            } 
            return fileList; 
 
        } 
        return null; 
 
 
    } 
    ////////////handler///// 
    private Handler myHandler = new Handler() { 
        @Override 
        public void handleMessage(Message msg) { 
            Log.i(TAG,"handleMessage msg===" + msg); 
            if (msg.what == -1) { 
                Toast.makeText(mContext, "not find file!", Toast.LENGTH_LONG).show(); 
                return; 
            }else { 
                Toast.makeText(mContext, "upload success!", Toast.LENGTH_LONG).show(); 
            } 
 
        } 
 
    };

3 项目demo代码地址:

https://github.com/ranke/HttpAsyncTest

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/aiops/3274.html

(0)
上一篇 2021年7月16日 14:27
下一篇 2021年7月16日 14:27

相关推荐

发表回复

登录后才能评论