Android(安卓)基于Http协议的文件上传
16lz
2021-01-24
本文介绍的基于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();}}
更多相关文章
- Android(安卓)获取Root权限 详细图解
- [置顶] Android:图解Activity启动流程源码(整体流程)
- 第一行代码 第三章 RecyclerView
- 八款Android(安卓)开发者必备的小工具
- AndroidR系统启动详细分析-学习笔记
- OpenJDK将对Android开发产生怎样的影响?
- Android(安卓)屏幕适配解决方案
- Android中文件读写操作
- 下载AOSP android源码(最小最快下载方式,跳过编译直接导入Android(