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 = "\r\n";
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);
}

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

android中的文件(图片)上传的更多相关文章

  1. Retrofit 2.0 轻松实现多文件/图片上传/Json字符串/表单

    如果嫌麻烦直接可以用我封装好的库:Novate: https://github.com/Tamicer/Novate 通过对Retrofit2.0的前两篇的基础入门和案例实践,掌握了怎么样使用Retr ...

  2. Aps.net中基于bootstrapt图片上传插件的应用

    Aps.net中基于bootstrapt图片上传插件的应用 在最近的项目中需要使用一个图片上传的功能,而且是多张图片同时上传到服务器的文件夹中,将图片路径存放在数据库中.为了外观好看使用了bootst ...

  3. WebUploader文件图片上传插件的使用

    最近在项目中用到了百度的文件图片上传插件WebUploader.分享给大家 需要在http://fex.baidu.com/webuploader/download.html点击打开链接下载WebUp ...

  4. Android Http实现文件的上传和下载

    最近做一个项目,其中涉及到文件的上传和下载功能,大家都知道,这个功能实现其实已经烂大街了,遂.直接从网上荡了一堆代码用,结果,发现网上的代码真是良莠不齐,不是写的不全面,就是有问题,于是自己重新整理了 ...

  5. commons-fileload图片文件上传工具 , servlet文件图片上传案列

    本案列是java  maven工程小项目,提供个大家学习! 1.在pom.xml文件中导入依赖: <!--文件上传依赖--><dependency> <groupId&g ...

  6. 从web编辑器 UEditor 中单独提取图片上传,包含多图片单图片上传以及在线涂鸦功能

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码.(抄的...) UEditor是非常好用的富文 ...

  7. [iOS AFNetworking框架实现HTTP请求、多文件图片上传下载]

    简单的JSON的HTTP传输就不说了,看一个简单的DEMO吧. 主要明白parameters是所填参数,类型是字典型.我把这部分代码封装起来了,以便多次调用.也许写在一起更清楚点. #pragma m ...

  8. android下大文件分割上传

    由于android自身的原因,对大文件(如影视频文件)的操作很容易造成OOM,即:Dalvik堆内存溢出,利用文件分割将大文件分割为小文件可以解决问题. 文件分割后分多次请求服务. //文件分割上传 ...

  9. WebApi2 文件图片上传下载

    Asp.Net Framework webapi2 文件上传与下载 前端界面采用Ajax的方式执行 一.项目结构 1.App_Start配置了跨域访问,以免请求时候因跨域问题不能提交.具体的跨域配置方 ...

  10. Django中怎么做图片上传--图片展示

    1.首先是html页面的form表单的三大属性,action是提交到哪,method是提交方式,enctype只要有图片上传就要加这个属性 Django框架自带csrf_token ,所以需要在前端页 ...

随机推荐

  1. 2016-2017 ACM Central Region of Russia Quarterfinal Programming Contest

    2016-2017 ACM Central Region of Russia Quarterfinal Programming Contest A. Fried Fish 题意:有N条鱼,有一个同时可 ...

  2. 【[TJOI2007]可爱的质数】

    题目 用一道板子题来复习一下\(bsgs\) \(bsgs\)用于求解形如 \[a^x\equiv b(mod\ p)\] 这样的高次不定方程 由于费马小定理的存在,我们可是直接暴力扫一遍\(p\), ...

  3. 布局方式-inline-block布局

    .像文本一样排block元素 .没有清除浮动等问题 .需要处理间隙     一种方式 <style> .container{ width: 800px; height: 200px; fo ...

  4. 使用paramiko的问题记录

    用paramiko时遇到问题,异常如下: 解决方法记录如下: 更新gmp版本: wget https://ftp.gnu.org/gnu/gmp/gmp-6.0.0a.tar.bz2 tar -xvj ...

  5. Python—XML

    什么是xml XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 标签没有被 ...

  6. Asset Store 下载的package存在什么地方?

    发现从Asset store下载的packages都不知道放在了什么地方 Windows 7,C:\Users\<username>\AppData\Roaming\Unity\Asset ...

  7. JavaScript函数的方法

    在一个对象中绑定函数,称为这个对象的方法. 在JavaScript中,对象的定义是: var xiaoming = { name:'小明'; birth:1990; }; 但是,如果我们给xiaomi ...

  8. dual表详解

    dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录.我们可以用它来做很多事情,如下: 1.查看当前用户 SQL> select user from ...

  9. 解析 Nginx 负载均衡策略

    转载:https://www.cnblogs.com/wpjamer/articles/6443332.html 1 前言 随着网站负载的不断增加,负载均衡(load balance)已不是陌生话题. ...

  10. C++ string和int相互转换

    首先需要C++ 11的支持 打开devC++,点击tools,点击编译环境,然后出现的框第一个勾选,输入-std=c++11即可 然后使用 to_string() 和 atoi() 就可以轻松实现其相 ...