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. POJ 1632 Vase collection【状态压缩+搜索】

    题目传送门:http://poj.org/problem?id=1632 Vase collection Time Limit: 1000MS   Memory Limit: 10000K Total ...

  2. sst上传和下载码云

    第一次 Team-----share---->Add----->commit-------remote----->pull 第二次 直接share开始.

  3. E: Unable to locate package

    E: Unable to locate package apt-get不能定位到包,有两种情况,一种是自己输入的包名字错误,确实找不到.另一种可能是执行sudo apt-get install之前更换 ...

  4. Openresty最佳案例 | 第3篇:Openresty的安装

    转载请标明出处: http://blog.csdn.net/forezp/article/details/78616645 本文出自方志朋的博客 我的服务器为一台全新的centos 7的服务器,所以从 ...

  5. 如何使用Xcode的Targets来管理开发和生产版本的构建

    如何使用Xcode的Targets来管理开发和生产版本的构建 想象一下,你已经完成了应用程序的开发和测试,现在准备提交正式版本.问题是,一些web服务的url指向了测试服务器,同时API密钥被配置用于 ...

  6. SQL Server中的三种Join方式

      1.测试数据准备 参考:Sql Server中的表访问方式Table Scan, Index Scan, Index Seek 这篇博客中的实验数据准备.这两篇博客使用了相同的实验数据. 2.SQ ...

  7. redis 高性能应用

    redis可达到512M/per key 512M=512*1024KB=512*1024*1000B=512*1024*1000*8bit=40亿+ 化整为零40亿,也就是说一位代表一个用户,40亿 ...

  8. (eclipse)统一文件编码和代码风格

    前言 1>每个人的代码风格不一样,以至于代码各式各样,有习惯=号左右加空格的,有习惯不加的,此举有时还会影响svn提交代码 2>注释代码不一样,并且注释风格也不一样 统一文件编码和代码风格 ...

  9. Super Reduced String

    https://www.hackerrank.com/challenges/reduced-string/problem He wants to reduce the string to its sh ...

  10. mysql修改登录密码三种方式

    一.用SET PASSWORD命令 首先登录MySQL,使用mysql自带的那个客户端连接上mysql.  格式:mysql> set password for 用户名@localhost = ...