Android基于Http协议实现文件上传功能的方法
本文实例讲述了Android基于Http协议实现文件上传功能的方法。分享给大家供大家参考,具体如下:
注意一般使用Http协议上传的文件都比较小,一般是小于2M
这里示例是上传一个小的MP3文件
1.主Activity:MainActivity.java
publicclassMainActivityextendsActivity { privatestaticfinalStringTAG="MainActivity"; privateEditTexttimelengthText; privateEditTexttitleText; privateEditTextvideoText; @Override publicvoidonCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //提交上传按钮 Buttonbutton=(Button)this.findViewById(R.id.button); timelengthText=(EditText)this.findViewById(R.id.timelength); videoText=(EditText)this.findViewById(R.id.video); titleText=(EditText)this.findViewById(R.id.title); button.setOnClickListener(newView.OnClickListener() { @Override publicvoidonClick(Viewv) { Stringtitle=titleText.getText().toString(); Stringtimelength=timelengthText.getText().toString(); Map<String,String>params=newHashMap<String,String>(); params.put("method","save"); params.put("title",title); params.put("timelength",timelength); try { //得到SDCard的目录 FileuploadFile=newFile(Environment.getExternalStorageDirectory(),videoText.getText().toString()); //上传音频文件 FormFileformfile=newFormFile("02.mp3",uploadFile,"video","audio/mpeg"); SocketHttpRequester.post("http://192.168.1.100:8080/videoweb/video/manage.do",params,formfile); Toast.makeText(MainActivity.this,R.string.success,1).show(); } catch(Exceptione) { Toast.makeText(MainActivity.this,R.string.error,1).show(); Log.e(TAG,e.toString()); } } }); } }
2.上传工具类,注意里面构造协议字符串需要根据不同的提交表单来处理
publicclassSocketHttpRequester { /** *发送xml数据 *@parampath请求地址 *@paramxmlxml数据 *@paramencoding编码 *@return *@throwsException */ publicstaticbyte[]postXml(Stringpath,Stringxml,Stringencoding)throwsException{ byte[]data=xml.getBytes(encoding); URLurl=newURL(path); HttpURLConnectionconn=(HttpURLConnection)url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setRequestProperty("Content-Type","text/xml;charset="+encoding); conn.setRequestProperty("Content-Length",String.valueOf(data.length)); conn.setConnectTimeout(5*1000); OutputStreamoutStream=conn.getOutputStream(); outStream.write(data); outStream.flush(); outStream.close(); if(conn.getResponseCode()==200){ returnreadStream(conn.getInputStream()); } returnnull; } /** *直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能: *<FORMMETHOD=POSTACTION="http://192.168.0.200:8080/ssi/fileload/test.do"enctype="multipart/form-data"> <INPUTTYPE="text"NAME="name"> <INPUTTYPE="text"NAME="id"> <inputtype="file"name="imagefile"/> <inputtype="file"name="zip"/> </FORM> *@parampath上传路径(注:避免使用localhost或127.0.0.1这样的路径测试, *因为它会指向手机模拟器,你可以使用http://www.baidu.com或http://192.168.1.10:8080这样的路径测试) *@paramparams请求参数key为参数名,value为参数值 *@paramfile上传文件 */ publicstaticbooleanpost(Stringpath,Map<String,String>params,FormFile[]files)throwsException { //数据分隔线 finalStringBOUNDARY="---------------------------7da2137580612"; //数据结束标志"---------------------------7da2137580612--" finalStringendline="--"+BOUNDARY+"--/r/n"; //下面两个for循环都是为了得到数据长度参数,依据表单的类型而定 //首先得到文件类型数据的总长度(包括文件分割线) intfileDataLength=0; for(FormFileuploadFile:files) { StringBuilderfileExplain=newStringBuilder(); fileExplain.append("--"); fileExplain.append(BOUNDARY); fileExplain.append("/r/n"); fileExplain.append("Content-Disposition:form-data;name=/""+uploadFile.getParameterName()+"/";filename=/""+uploadFile.getFilname()+"/"/r/n"); fileExplain.append("Content-Type:"+uploadFile.getContentType()+"/r/n/r/n"); fileExplain.append("/r/n"); fileDataLength+=fileExplain.length(); if(uploadFile.getInStream()!=null){ fileDataLength+=uploadFile.getFile().length(); }else{ fileDataLength+=uploadFile.getData().length; } } //再构造文本类型参数的实体数据 StringBuildertextEntity=newStringBuilder(); for(Map.Entry<String,String>entry:params.entrySet()) { textEntity.append("--"); textEntity.append(BOUNDARY); textEntity.append("/r/n"); textEntity.append("Content-Disposition:form-data;name=/""+entry.getKey()+"/"/r/n/r/n"); textEntity.append(entry.getValue()); textEntity.append("/r/n"); } //计算传输给服务器的实体数据总长度(文本总长度+数据总长度+分隔符) intdataLength=textEntity.toString().getBytes().length+fileDataLength+endline.getBytes().length; URLurl=newURL(path); //默认端口号其实可以不写 intport=url.getPort()==-1?80:url.getPort(); //建立一个Socket链接 Socketsocket=newSocket(InetAddress.getByName(url.getHost()),port); //获得一个输出流(从Android流到web) OutputStreamoutStream=socket.getOutputStream(); //下面完成HTTP请求头的发送 Stringrequestmethod="POST"+url.getPath()+"HTTP/1.1/r/n"; outStream.write(requestmethod.getBytes()); //构建accept Stringaccept="Accept:image/gif,image/jpeg,image/pjpeg,image/pjpeg,application/x-shockwave-flash,application/xaml+xml,application/vnd.ms-xpsdocument,application/x-ms-xbap,application/x-ms-application,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/*/r/n"; outStream.write(accept.getBytes()); //构建language Stringlanguage="Accept-Language:zh-CN/r/n"; outStream.write(language.getBytes()); //构建contenttype Stringcontenttype="Content-Type:multipart/form-data;boundary="+BOUNDARY+"/r/n"; outStream.write(contenttype.getBytes()); //构建contentlength Stringcontentlength="Content-Length:"+dataLength+"/r/n"; outStream.write(contentlength.getBytes()); //构建alive Stringalive="Connection:Keep-Alive/r/n"; outStream.write(alive.getBytes()); //构建host Stringhost="Host:"+url.getHost()+":"+port+"/r/n"; outStream.write(host.getBytes()); //写完HTTP请求头后根据HTTP协议再写一个回车换行 outStream.write("/r/n".getBytes()); //把所有文本类型的实体数据发送出来 outStream.write(textEntity.toString().getBytes()); //把所有文件类型的实体数据发送出来 for(FormFileuploadFile:files) { StringBuilderfileEntity=newStringBuilder(); fileEntity.append("--"); fileEntity.append(BOUNDARY); fileEntity.append("/r/n"); fileEntity.append("Content-Disposition:form-data;name=/""+uploadFile.getParameterName()+"/";filename=/""+uploadFile.getFilname()+"/"/r/n"); fileEntity.append("Content-Type:"+uploadFile.getContentType()+"/r/n/r/n"); outStream.write(fileEntity.toString().getBytes()); //边读边写 if(uploadFile.getInStream()!=null) { byte[]buffer=newbyte[1024]; intlen=0; while((len=uploadFile.getInStream().read(buffer,0,1024))!=-1) { outStream.write(buffer,0,len); } uploadFile.getInStream().close(); } else { outStream.write(uploadFile.getData(),0,uploadFile.getData().length); } outStream.write("/r/n".getBytes()); } //下面发送数据结束标志,表示数据已经结束 outStream.write(endline.getBytes()); BufferedReaderreader=newBufferedReader(newInputStreamReader(socket.getInputStream())); //读取web服务器返回的数据,判断请求码是否为200,如果不是200,代表请求失败 if(reader.readLine().indexOf("200")==-1) { returnfalse; } outStream.flush(); outStream.close(); reader.close(); socket.close(); returntrue; } /** *提交数据到服务器 *@parampath上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.baidu.com或http://192.168.1.10:8080这样的路径测试) *@paramparams请求参数key为参数名,value为参数值 *@paramfile上传文件 */ publicstaticbooleanpost(Stringpath,Map<String,String>params,FormFilefile)throwsException { returnpost(path,params,newFormFile[]{file}); } /** *提交数据到服务器 *@parampath上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.baidu.com或http://192.168.1.10:8080这样的路径测试) *@paramparams请求参数key为参数名,value为参数值 *@paramencode编码 */ publicstaticbyte[]postFromHttpClient(Stringpath,Map<String,String>params,Stringencode)throwsException { //用于存放请求参数 List<NameValuePair>formparams=newArrayList<NameValuePair>(); for(Map.Entry<String,String>entry:params.entrySet()) { formparams.add(newBasicNameValuePair(entry.getKey(),entry.getValue())); } UrlEncodedFormEntityentity=newUrlEncodedFormEntity(formparams,encode); HttpPosthttppost=newHttpPost(path); httppost.setEntity(entity); //看作是浏览器 HttpClienthttpclient=newDefaultHttpClient(); //发送post请求 HttpResponseresponse=httpclient.execute(httppost); returnreadStream(response.getEntity().getContent()); } /** *发送请求 *@parampath请求路径 *@paramparams请求参数key为参数名称value为参数值 *@paramencode请求参数的编码 */ publicstaticbyte[]post(Stringpath,Map<String,String>params,Stringencode)throwsException { //Stringparams="method=save&name="+URLEncoder.encode("老毕","UTF-8")+"&age=28&";//需要发送的参数 StringBuilderparambuilder=newStringBuilder(""); if(params!=null&&!params.isEmpty()) { for(Map.Entry<String,String>entry:params.entrySet()) { parambuilder.append(entry.getKey()).append("=") .append(URLEncoder.encode(entry.getValue(),encode)).append("&"); } parambuilder.deleteCharAt(parambuilder.length()-1); } byte[]data=parambuilder.toString().getBytes(); URLurl=newURL(path); HttpURLConnectionconn=(HttpURLConnection)url.openConnection(); //设置允许对外发送请求参数 conn.setDoOutput(true); //设置不进行缓存 conn.setUseCaches(false); conn.setConnectTimeout(5*1000); conn.setRequestMethod("POST"); //下面设置http请求头 conn.setRequestProperty("Accept","image/gif,image/jpeg,image/pjpeg,image/pjpeg,application/x-shockwave-flash,application/xaml+xml,application/vnd.ms-xpsdocument,application/x-ms-xbap,application/x-ms-application,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/*"); conn.setRequestProperty("Accept-Language","zh-CN"); conn.setRequestProperty("User-Agent","Mozilla/4.0(compatible;MSIE8.0;WindowsNT5.2;Trident/4.0;.NETCLR1.1.4322;.NETCLR2.0.50727;.NETCLR3.0.04506.30;.NETCLR3.0.4506.2152;.NETCLR3.5.30729)"); conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length",String.valueOf(data.length)); conn.setRequestProperty("Connection","Keep-Alive"); //发送参数 DataOutputStreamoutStream=newDataOutputStream(conn.getOutputStream()); outStream.write(data);//把参数发送出去 outStream.flush(); outStream.close(); if(conn.getResponseCode()==200) { returnreadStream(conn.getInputStream()); } returnnull; } /** *读取流 *@paraminStream *@return字节数组 *@throwsException */ publicstaticbyte[]readStream(InputStreaminStream)throwsException { ByteArrayOutputStreamoutSteam=newByteArrayOutputStream(); byte[]buffer=newbyte[1024]; intlen=-1; while((len=inStream.read(buffer))!=-1) { outSteam.write(buffer,0,len); } outSteam.close(); inStream.close(); returnoutSteam.toByteArray(); } } publicclassStreamTool { /** *从输入流读取数据 *@paraminStream *@return *@throwsException */ publicstaticbyte[]readInputStream(InputStreaminStream)throwsException{ ByteArrayOutputStreamoutSteam=newByteArrayOutputStream(); byte[]buffer=newbyte[1024]; intlen=0; while((len=inStream.read(buffer))!=-1){ outSteam.write(buffer,0,len); } outSteam.close(); inStream.close(); returnoutSteam.toByteArray(); } } /** *使用JavaBean封装上传文件数据 * */ publicclassFormFile { //上传文件的数据 privatebyte[]data; privateInputStreaminStream; privateFilefile; //文件名称 privateStringfilname; //请求参数名称 privateStringparameterName; //内容类型 privateStringcontentType="application/octet-stream"; /** *上传小文件,把文件数据先读入内存 *@paramfilname *@paramdata *@paramparameterName *@paramcontentType */ publicFormFile(Stringfilname,byte[]data,StringparameterName,StringcontentType) { this.data=data; this.filname=filname; this.parameterName=parameterName; if(contentType!=null)this.contentType=contentType; } /** *上传大文件,一边读文件数据一边上传 *@paramfilname *@paramfile *@paramparameterName *@paramcontentType */ publicFormFile(Stringfilname,Filefile,StringparameterName,StringcontentType) { this.filname=filname; this.parameterName=parameterName; this.file=file; try { this.inStream=newFileInputStream(file); } catch(FileNotFoundExceptione) { e.printStackTrace(); } if(contentType!=null)this.contentType=contentType; } publicFilegetFile() { returnfile; } publicInputStreamgetInStream() { returninStream; } publicbyte[]getData() { returndata; } publicStringgetFilname() { returnfilname; } publicvoidsetFilname(Stringfilname) { this.filname=filname; } publicStringgetParameterName() { returnparameterName; } publicvoidsetParameterName(StringparameterName) { this.parameterName=parameterName; } publicStringgetContentType() { returncontentType; } publicvoidsetContentType(StringcontentType) { this.contentType=contentType; } }
更多关于Android相关内容感兴趣的读者可查看本站专题:《Android文件操作技巧汇总》、《Android操作SQLite数据库技巧总结》、《Android操作json格式数据技巧总结》、《Android数据库操作技巧总结》、《Android编程之activity操作技巧总结》、《Android编程开发之SD卡操作方法汇总》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》、《Android视图View技巧总结》及《Android控件用法总结》
希望本文所述对大家Android程序设计有所帮助。