本文介绍的基于Http协议的文件上传方法,Http协议文件上传的功能是通过RFC1867规范描述的,Chrome,IE,Mozila和Opera等浏览器都支持此功能。

这里我先介绍一个工具名字叫Fiddler,它是一个Web Debugger工具,我们这里用它去分析Http 上传文件的原始内容 ,格式如下:


POST http://192.168.1.100/Handler1.ashx HTTP/1.1
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
User-Agent: Fiddler
Host: 192.168.1.100
Content-Length: 263827


---------------------------acebdf13572468
Content-Disposition: form-data; name="fieldNameHere"; filename="QQ截图20140818223203.png"
Content-Type: image/png











Android利用Http协议上传文件也必须要遵循这个规范。所以我们代码的核心就是如何用代码实现这个规范,从而实现文件的上传,上面说了一些废话。

下面进入主题 

首先 要说明的一点是 由于上传是需要访问网络的,

所以一定要在AndroidManifest.xml 文件中添加访问网络的权限,如下所示:

                

上传文件的代码

package com.example.imageupload.network;import java.io.DataOutputStream;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.UUID;import java.io.File;public class UpFile {public static int post(String actionUrl, File file) throws IOException {//产生随机分隔内容String BOUNDARY = UUID.randomUUID().toString();String PREFIX = "--";String LINEND = "\r\n";String MULTIPART_FROM_DATA = "multipart/form-data";String CHARSET = "UTF-8";URL url = new URL(actionUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();//设置超时时间单位是毫秒conn.setReadTimeout(5 * 1000);//设置允许输入conn.setDoInput(true);//设置允许输出conn.setDoOutput(true);//不允许使用缓存conn.setUseCaches(false);//设置请求的方法为Postconn.setRequestMethod("POST");//设置维持长连接conn.setRequestProperty("Connection", "keep-alive");//设置字符集为UTF-8conn.setRequestProperty("Charset", CHARSET);//设置文件的类型conn.setRequestProperty("Content-type", MULTIPART_FROM_DATA + "; boundary=" + BOUNDARY);DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());//发送文件数据if (file != null) {StringBuilder sb = new StringBuilder();sb.append(PREFIX);sb.append(BOUNDARY);sb.append(LINEND);sb.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"" + LINEND);sb.append("Content-Type: image/png"  + LINEND);sb.append(LINEND);//写入输出流中outStream.write(sb.toString().getBytes());//将文件读入输入流中InputStream is = new FileInputStream(file);byte[] buffer = new byte[1024];int len = -1;//写入输出流中while ((len = is.read(buffer)) != -1) {outStream.write(buffer, 0, len);}is.close();//添加换行标识outStream.write(LINEND.getBytes());}byte[] endData = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();outStream.write(endData);//发送数据outStream.flush();//获取响应码 上传成功返回的是200int res = conn.getResponseCode();return res;}}

还有说明的一点是,网络的操作一定要在子线程里完成, 否则会产生异常 

代码如下:

class Task extends AsyncTask {@Overrideprotected Integer doInBackground(String... strings) {Integer result = -1;try {result = UpFile.post("http://192.168.1.100/Handler1.ashx", new File(strings[0]));}catch (IOException e) {e.printStackTrace();}//result = UploadFile.upLoadFile("http://192.168.1.100/Handler1.ashx",//new File(strings[0]));return result;}@Overrideprotected void onPostExecute(Integer result) {Toast.makeText(MainActivity.this, "" + result, Toast.LENGTH_LONG).show();}}


更多相关文章

  1. Android(安卓)获取Root权限 详细图解
  2. [置顶] Android:图解Activity启动流程源码(整体流程)
  3. 第一行代码 第三章 RecyclerView
  4. 八款Android(安卓)开发者必备的小工具
  5. AndroidR系统启动详细分析-学习笔记
  6. OpenJDK将对Android开发产生怎样的影响?
  7. Android(安卓)屏幕适配解决方案
  8. Android中文件读写操作
  9. 下载AOSP android源码(最小最快下载方式,跳过编译直接导入Android(

随机推荐

  1. android之模拟手机助手下载
  2. 报错记录-The option ‘android.enableUn
  3. android 如何判断开机完成
  4. Java中的WeakReference 和 SoftReference
  5. Android Studio 更换debug.keystore问题
  6. Android 4.0 Launcher2源码分析——导入e
  7. Android RxJava:一步步带你源码分析 RxJav
  8. Android Telephony启动过程源码分析
  9. Android中Handler的简析
  10. Android Handler Looper