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. winform 实现彩票功能

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/MrTraum/article/details/32702319 watermark/2/text/a ...

  2. Docker 常用指令

    1.检查内核版本,必须是3.10及以上uname ‐r2.安装dockeryum install docker3.输入y确认安装4.启动docker[root@localhost ~]# system ...

  3. 使用TextView/EditText应该注意的地方,监听EditText,addTextChangedListener

    http://blog.csdn.net/huichengongzi/article/details/7818676 监听 EditText 控件: addTextChangedListener(ne ...

  4. Android学习笔记_34_自定义窗口标题

    1.建好项目之后在它的layout文件夹下创建一个title.xml文件,作为自定义窗口标题的文件. <?xml version="1.0" encoding="u ...

  5. SpringBoot非官方教程 | 第二十三篇: 异步方法

    转载请标明出处: 原文首发于https://www.fangzhipeng.com/springboot/2017/07/11/springboot-ansy/ 本文出自方志朋的博客 这篇文章主要介绍 ...

  6. Question 20171114 String的一些问题?

    欢迎各位大神提问题及补充不足和警醒错误! Question 20171113  Java中char为什么占用两个字节? Java是使用Unicode编码的所以Java会将源代码以Unicode的方式编 ...

  7. Long数组转String数组

    public static String[] longToString(Long longArray[]) { if (longArray == null || longArray.length &l ...

  8. 工作流,WEB框架,UI组件网络收集整理

    工作流,WEB框架,UI组件网络收集整理 在博客园上逛了好多年,随手收录了一些工作流,WEB开发框架,UI组件,现在整理一下与大家分享. 由于个人能力与精力有限,望各位园友在评论中补充,我将全部整理到 ...

  9. oracle中lock和latch的用途

    本文向各位阐述Oracle的Latch机制,Latch,用金山词霸翻译是门插栓,闭锁,专业术语叫锁存器,我开始接触时就不大明白为什么不写Lock,不都是锁吗?只是翻译不同而以?研究过后才知道两者有很大 ...

  10. django写一个简单的登陆注册

    要写这个,前提还是需要知道三个知识: 一个是urls.py,它是写我们的路由关系的,之前我写了通过wsgiref写一个简单的服务端,也用到了路由,就是 请求过来的url和视图函数的对应关系. 二是就是 ...