Android 基于Http协议的文件上传

本文介绍的基于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协议的文件上传_第1张图片










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

下面进入主题 

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

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />
	
    <uses-permission android:name="android.permission.INTERNET" />

    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

上传文件的代码

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);
		//设置请求的方法为Post
		conn.setRequestMethod("POST");
		//设置维持长连接
		conn.setRequestProperty("Connection", "keep-alive");
		//设置字符集为UTF-8
		conn.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();
		//获取响应码 上传成功返回的是200
		int res = conn.getResponseCode();
		return res;
		
	}

}

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

代码如下:

class Task extends AsyncTask<String, Integer, Integer> {

		@Override
		protected 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;
		}

		@Override
		protected void onPostExecute(Integer result) {
			Toast.makeText(MainActivity.this, "" + result, Toast.LENGTH_LONG).show();
		}
	}


你可能感兴趣的:(android,网络,APP,http协议)