我需要将我正在开发的应用程序中的图像上传到服务器,并且我想知道如何使用Google Volley开发Multipart Request来加载图像。
由于
答案 0 :(得分:14)
我有一个按Google Volley
上传图片的示例。看看:
package net.colaborativa.exampleapp.api;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import com.android.volley.AuthFailureError;
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.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;
public class PhotoMultipartRequest<T> extends Request<T> {
private static final String FILE_PART_NAME = "file";
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
private final Response.Listener<T> mListener;
private final File mImageFile;
protected Map<String, String> headers;
public PhotoMultipartRequest(String url, ErrorListener errorListener, Listener<T> listener, File imageFile){
super(Method.POST, url, errorListener);
mListener = listener;
mImageFile = imageFile;
buildMultipartEntity();
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
headers.put("Accept", "application/json");
return headers;
}
private void buildMultipartEntity(){
mBuilder.addBinaryBody(FILE_PART_NAME, mImageFile, ContentType.create("image/jpeg"), mImageFile.getName());
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
@Override
public String getBodyContentType(){
String contentTypeHeader = mBuilder.build().getContentType().getValue();
return contentTypeHeader;
}
@Override
public byte[] getBody() throws AuthFailureError{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mBuilder.build().writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
}
return bos.toByteArray();
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
T result = null;
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
}
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}
你可以像这样使用它:
RequestQueue mQueue = Volley.newRequestQueue(context);
PhotoMultipartRequest imageUploadReq = new PhotoMultipartRequest(url, ErrorListener, Listener, imageFile);
mQueue.add(imageUploadReq);
我希望这些代码会激励你。
答案 1 :(得分:5)
@silverknight的答案有效,但是,我还必须在build.gradle
中添加以下内容来解决httpcomponents
依赖项:
android {
...
// have to exclude these otherwise you'll get:
// Error:Gradle: Execution failed for task: ... com.android.builder.packaging.DuplicateFileException: ...
packagingOptions {
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
}
}
dependencies {
...
compile 'com.android.volley:volley:1.0.0'
compile('org.apache.httpcomponents:httpmime:4.3.6') {
exclude module: 'httpclient'
}
compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1'
}
注意:请勿使用org.apache.httpcomponents:httpclient
您应该避免使用标准版'org.apache.httpcomponents:httpclient:4.5.2'
如果您尝试:
android {
...
}
dependencies {
...
compile 'com.android.volley:volley:1.0.0'
compile 'org.apache.httpcomponents:httpcore:4.4.4'
compile 'org.apache.httpcomponents:httpmime:4.5.2'
compile('org.apache.httpcomponents:httpclient:4.5.2'
}
你会得到:
java.lang.NoSuchFieldError: No static field INSTANCE of type Lorg/apache/http/message/BasicHeaderValueFormatter; in class Lorg/apache/http/message/BasicHeaderValueFormatter; or its superclasses (declaration of 'org.apache.http.message.BasicHeaderValueFormatter' appears in /system/framework/ext.jar)
,您应该使用httpclient
的Android端口
注意:使用org.apache.httpcomponents:httpmime:4.3.6
您 使用org.apache.httpcomponents:httpmime:4.3.6
,您无法超越版本4.3.x
。例如,您可能想要使用最新版本的httpmime
,在撰写本文时4.5.2:
android {
...
}
dependencies {
...
compile('org.apache.httpcomponents:httpmime:4.5.2') {
exclude module: 'httpclient'
}
compile 'org.apache.httpcomponents:httpclient-android:4.3.5.1'
使用此配置,您将在调用PhotoMultipartRequest
时获得以下内容:
java.lang.NoSuchMethodError: No static method create(Ljava/lang/String;[Lorg/apache/http/NameValuePair;)Lorg/apache/http/entity/ContentType; in class Lorg/apache/http/entity/ContentType; or its super classes (declaration of 'org.apache.http.entity.ContentType' appears in /xxx/base.apk)