android Volley 上传文件上传图片
Volley不解释了吧, android 官方的一个网络请求库.
源码的地址在:
git@github.com:com314159/VolleyMultiPartRequest.git
上面的是ssh
以下的是http地址
https://github.com/com314159/VolleyMultiPartRequest
是依据
https://github.com/smanikandan14/Volley-demo
这位大神改动而来的, 可是那位大神的代码有bug, 上传文件不成功.
注: 我的demo里面还集成了okhttp, 不须要的同学不用理这个类就可以
实现方法:
1.加入三个jar包,
httpcore-4.3.2.jar
httpclient-4.3.5.jar
httpmime-4.3.5.jar
2.实现MultiPartStack
package com.example.volleytest; import java.io.File;
import java.io.IOException;
import java.util.Map; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP; import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.HurlStack; /**
* @author ZhiCheng Guo
* @version 2014年10月7日 上午11:00:52 这个Stack用于上传文件, 假设没有这个Stack, 则上传文件不成功
*/
public class MultiPartStack extends HurlStack {
@SuppressWarnings("unused")
private static final String TAG = MultiPartStack.class.getSimpleName();
private final static String HEADER_CONTENT_TYPE = "Content-Type"; @Override
public HttpResponse performRequest(Request<? > request,
Map<String, String> additionalHeaders) throws IOException, AuthFailureError { if(!(request instanceof MultiPartRequest)) {
return super.performRequest(request, additionalHeaders);
}
else {
return performMultiPartRequest(request, additionalHeaders);
}
} private static void addHeaders(HttpUriRequest httpRequest, Map<String, String> headers) {
for (String key : headers.keySet()) {
httpRequest.setHeader(key, headers.get(key));
}
} public HttpResponse performMultiPartRequest(Request<? > request,
Map<String, String> additionalHeaders) throws IOException, AuthFailureError {
HttpUriRequest httpRequest = createMultiPartRequest(request, additionalHeaders);
addHeaders(httpRequest, additionalHeaders);
addHeaders(httpRequest, request.getHeaders());
HttpParams httpParams = httpRequest.getParams();
int timeoutMs = request.getTimeoutMs();
// TODO: Reevaluate this connection timeout based on more wide-scale
// data collection and possibly different for wifi vs. 3G.
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, timeoutMs); /* Make a thread safe connection manager for the client */
HttpClient httpClient = new DefaultHttpClient(httpParams); return httpClient.execute(httpRequest);
} static HttpUriRequest createMultiPartRequest(Request<?> request,
Map<String, String> additionalHeaders) throws AuthFailureError {
switch (request.getMethod()) {
case Method.DEPRECATED_GET_OR_POST: {
// This is the deprecated way that needs to be handled for backwards compatibility.
// If the request's post body is null, then the assumption is that the request is
// GET. Otherwise, it is assumed that the request is a POST.
byte[] postBody = request.getBody();
if (postBody != null) {
HttpPost postRequest = new HttpPost(request.getUrl());
if(request.getBodyContentType() != null)
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
HttpEntity entity;
entity = new ByteArrayEntity(postBody);
postRequest.setEntity(entity);
return postRequest;
} else {
return new HttpGet(request.getUrl());
}
}
case Method.GET:
return new HttpGet(request.getUrl());
case Method.DELETE:
return new HttpDelete(request.getUrl());
case Method.POST: {
HttpPost postRequest = new HttpPost(request.getUrl());
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setMultiPartBody(postRequest,request);
return postRequest;
}
case Method.PUT: {
HttpPut putRequest = new HttpPut(request.getUrl());
if(request.getBodyContentType() != null)
putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setMultiPartBody(putRequest,request);
return putRequest;
}
// Added in source code of Volley libray.
case Method.PATCH: {
HttpPatch patchRequest = new HttpPatch(request.getUrl());
if(request.getBodyContentType() != null)
patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
return patchRequest;
}
default:
throw new IllegalStateException("Unknown request method.");
}
} /**
* If Request is MultiPartRequest type, then set MultipartEntity in the
* httpRequest object.
*
* @param httpRequest
* @param request
* @throws AuthFailureError
*/
private static void setMultiPartBody(HttpEntityEnclosingRequestBase httpRequest,
Request<?> request) throws AuthFailureError { // Return if Request is not MultiPartRequest
if (!(request instanceof MultiPartRequest)) {
return;
} // MultipartEntity multipartEntity = new
// MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); /* example for setting a HttpMultipartMode */
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); // Iterate the fileUploads
Map<String, File> fileUpload = ((MultiPartRequest) request).getFileUploads();
for (Map.Entry<String, File> entry : fileUpload.entrySet()) { builder.addPart(((String) entry.getKey()), new FileBody((File) entry.getValue()));
} ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
// Iterate the stringUploads
Map<String, String> stringUpload = ((MultiPartRequest) request).getStringUploads();
for (Map.Entry<String, String> entry : stringUpload.entrySet()) {
try {
builder.addPart(((String) entry.getKey()),
new StringBody((String) entry.getValue(), contentType));
} catch (Exception e) {
e.printStackTrace();
}
} httpRequest.setEntity(builder.build());
} }
3. 实现MultiPartRequest, 这个接口是为了方便扩展
package com.example.volleytest; import java.io.File;
import java.util.Map; /**
* @author ZhiCheng Guo
* @version 2014年10月7日 上午11:04:36
*/
public interface MultiPartRequest { public void addFileUpload(String param,File file); public void addStringUpload(String param,String content); public Map<String,File> getFileUploads(); public Map<String,String> getStringUploads();
}
/**
* Copyright 2013 Mani Selvaraj
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package com.example.volleytest; import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map; import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser; /**
* MultipartRequest - To handle the large file uploads.
* Extended from JSONRequest. You might want to change to StringRequest based on your response type.
* @author Mani Selvaraj
*
*/
public class MultiPartStringRequest extends Request<String> implements MultiPartRequest{ private final Listener<String> mListener;
/* To hold the parameter name and the File to upload */
private Map<String,File> fileUploads = new HashMap<String,File>(); /* To hold the parameter name and the string content to upload */
private Map<String,String> stringUploads = new HashMap<String,String>(); /**
* Creates a new request with the given method.
*
* @param method the request {@link Method} to use
* @param url URL to fetch the string at
* @param listener Listener to receive the String response
* @param errorListener Error listener, or null to ignore errors
*/
public MultiPartStringRequest(int method, String url, Listener<String> listener,
ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
} public void addFileUpload(String param,File file) {
fileUploads.put(param,file);
} public void addStringUpload(String param,String content) {
stringUploads.put(param,content);
} /**
* 要上传的文件
*/
public Map<String,File> getFileUploads() {
return fileUploads;
} /**
* 要上传的參数
*/
public Map<String,String> getStringUploads() {
return stringUploads;
} @Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
} @Override
protected void deliverResponse(String response) {
if(mListener != null) {
mListener.onResponse(response);
}
} /**
* 空表示不上传
*/
public String getBodyContentType() {
return null;
}
}
3.用法和volley原生的request的用法是一样的, 仅仅是要使用新的Stack, 如以下的是put的方法的用法. 假设是post, 就改动成post方法就能够了
RequestQueue mSingleQueue = Volley.newRequestQueue(this, new MultiPartStack());
MultiPartStringRequest multiPartRequest = new MultiPartStringRequest(
Request.Method.PUT, url, responseListener, errorListener) {
@Override
public Map<String, File> getFileUploads() {
return files;
}
@Override
public Map<String, String> getStringUploads() {
return params;
}
};
mSingeQueue.add(multiPartRequest)
android Volley 上传文件上传图片的更多相关文章
- 使用Volley上传文件
使用浏览器上传文件,然后通过Wireshark抓包分析,发现发送的数据大概是这个样子. MIME Multipart Media Encapsulation, Type: multipart/form ...
- android 拍照上传文件 原生定位
最近公司需要一个android拍照上传和定位功能的的单一功能页面,一开始选择ionic cordova angular的一套H5框架,但是遇到和上传文件报错的问题,bug找了一天没找到原因,怀疑是io ...
- 关于Android WebView上传文件的解决方案
我们在开发需求的时候,难免会接入一下第三方的H5页面,有些H5页面是具有上传照片的功能,Android 中的 WebView是不能直接打开文件选择弹框的 接下来我讲简单提供一下解决方案,先说一下思路 ...
- C# HttpClient Post 参数同时上传文件 上传图片 调用接口
// 调用接口上传文件 using (var client = new HttpClient()) { using (var multipartFormDataContent = new Multip ...
- 如何使用PHP上传文件,上传图片,php上传教程,php表单文件上传教程
使用PHP进行文件上传,主要使用到表单功能和PHP内置的$_FILES函数功能.接下来我们看如何实现PHP上传功能.例子效果图,此例子是在Mac下进行调试成功的. PHP上传图片文件的功能代码如下: ...
- mono for android Json 上传文件
void button_Click(object sender, EventArgs e) { string Url = "上传地址,服务器端负责接收"; byte[] fbyte ...
- Android webview 上传文件不调用openFileChooser解决办法
html页面带有图片上传功能,关于使用openFileChooser方法去选择图片,并且在onActivityResult方法里面设置返回的图片url文件路径,网上有很多,再次不再赘述. 实践中发现, ...
- android 模拟器上传文件 Read-only file system
在cmd窗口一条命令就可以了:adb shellmount -o remount rw /
- android 上传文件
android对于上传文件,还是非常easy的,和java里面的上传都是一样的,基本上都是熟悉操作输出流和输入流!另一个特别重要的就是须要一些content-type这些參数的配置! 假设这些都弄好 ...
随机推荐
- git远程仓库创建及权限管理(二)多个项目
本文介绍ubutu下使用gitolite实现多项目的权限管理1.安装git sudo apt-get install git 2.设置Git的user name和email: git config - ...
- 从connect到express01-connect
介绍 Connect是一个node中间件框架.每个中间件在http处理过程中通过改写request, response的数据.状态,实现了特定的功能. 根据中间件在整个http处理流程的位置,将中间件 ...
- EASYUI DATAGRID加合计
想达到的效果(计算当前展示的20条的合计数量(一言难尽)): 参考http://www.jb51.net/article/85645.htm(万分感谢该文的作者) 相关代码: function onL ...
- TCP三次握手连接和TCP四次挥手及大量TIME_WAIT解决方法:
1.TCP建立连接,三次握手 建立的TCP连接可靠的连接,必须经过三次握手建立连接才能正式通信彼此传输数数据. 客户端请求服务端建立连接 第一次握手:客户给服务发送一个请求报文SYN, 客户端的状态置 ...
- iOS: 环信的推送
原文:http://m.blog.csdn.net/article/details?id=38824551 1.先创建一个apns证书,链接如下 http://developer.easemob.co ...
- 流畅的python第三章字典和集合学习记录
什么是可散列的数据类型 如果一个对象是可散列的,那么在这个对象的生命周期中,他的散列值是不变的,而且这个对象需要实现__hash__()方法.另外可散列对象还要有__qe__()方法.这样才能跟其他键 ...
- supervise 用来监控服务,自动启动
Atong介绍的这个工具,挺好用的.supervise 官方网站: https://cr.yp.to/daemontools.html cd /data/test cat test.c #includ ...
- Android SDK Manager 更新
Android SDK Manager 更新 解决国内访问Google服务器的困难: 1.启动 Android SDK Manager : 2.打开主界面,依次选择「Tools」.「Options…」 ...
- 云计算之路-试用Azure:拐弯抹角的负载均衡
负载均衡是云服务商标配的免费服务.阿里云的对应产品叫SLB,UCloud的对应产品叫ULB,操作都很简单直观,进入负载均衡管理控制台,添加负载均衡,选择相应的虚拟机即可. 而Azure则完全不一样,在 ...
- 创建CSS3警示框渐变动画
来源:GBin1.com 在线演示 在线下载 现代的网页设计技术已经允许开发人员在大多数浏览器中快速实现所支持的动画,其中消息警示是非常普遍的.由于默认的JavaScript警示框往往设计不佳和过 ...