如何post音频和图像作为multipart/formdata原生android?
How to post audio and image as multipart/formdata in native android?
我想post像这样形成数据,
其中,
- ApiKey,userid,albumid,music_name,singer_name为key对应的值都是text类型
- music_cover和music_file是图像文件和音频文件的键值。
All the values are non nullable. That is, must pass all values to the
server to get a success response.
所以,总而言之,我有一堆文本、音频和图像要使用来自 android 的 Web 服务上传到服务器。
我正在使用选择器选择图像和音频,所以我有它们的文件路径。
请指导我完成使用 android 的 multipart 上传音频和图像的过程。
它让我彻夜难眠,但没有任何缓解。
这里我使用 Volley 创建了一个示例
所以首先我们必须构建一个 RestApiMultiPartRequests.class
所以我在这里创建它是这样的
私有 class RestApiMultiPartRequests 扩展请求 {
private final Map<String, String> mStringParts;
private final Map<String, File> mFileParts;
private MultipartEntityBuilder mBuilder;
private final Response.Listener<T> mListener;
public RestApiMultiPartRequests(String url,
Map<String, String> stringParts,
Map<String, File> fileParts,
Response.Listener<T> listener,
Response.ErrorListener errorListener) {
super(Method.POST, url, errorListener);
mListener = listener;
mStringParts = stringParts;
mFileParts = fileParts;
buildMultipartEntity();
}
private void buildMultipartEntity() {
if (mBuilder != null) {
mBuilder = null;
}
mBuilder = MultipartEntityBuilder.create();
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setBoundary("_____" + Long.toString(System.currentTimeMillis()) + "_____");
mBuilder.setCharset(Consts.UTF_8);
if (mStringParts != null) {
for (Map.Entry<String, String> entry : mStringParts.entrySet()) {
mBuilder.addTextBody(entry.getKey(), entry.getValue(), ContentType.create("text/plain", Charset.forName("UTF-8")));
}
}
Log.e("Size", "Size: " + mFileParts.size());
for (Map.Entry<String, File> entry : mFileParts.entrySet()) {
ContentType imageContentType = ContentType.create("image/*");//MULTIPART_FORM_DATA;
Log.d("", "Key " + entry.getKey());
Log.d("", "Value " + entry.getValue());
Log.d("", "Name " + entry.getValue().getName());
//"userfile"
mBuilder.addBinaryBody(entry.getKey(), entry.getValue(), imageContentType, entry.getValue().getName());
}
}
@Override
public String getBodyContentType() {
return mBuilder.build().getContentType().getValue();
}
@Override
public byte[] getBody() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mBuilder.build().writeTo(bos);
} catch (IOException e) {
e.printStackTrace();
}
return bos.toByteArray();
}
public HttpEntity getEntity() {
return mBuilder.build();
}
@SuppressWarnings("unchecked")
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return (Response<T>) Response.success(jsonString, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}
使用这个 class 我们可以构建这样的请求
private void UploadImage() {
ServiceCall.RestApiMultiPartRequests<String> restApiMultiPartRequest =
new ServiceCall.RestApiMultiPartRequests<String>(url/*YOUR SERVICE URL*/, hashMap /* HASHMAP OF STRING */, fileparts /*HASH MAP OF FILE AND STRING */, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
/* HANDEL YOUR SUCCESS RESPONSE **/
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle your error types accordingly.For Timeout & No
// connection error, you can show 'retry' button.
// For AuthFailure, you can re login with user
// credentials.
// For ClientError, 400 & 401, Errors happening on
// client side when sending api request.
// In this case you can check how client is forming the
// api and debug accordingly.
// For ServerError 5xx, you can do retry or handle
// accordingly.
/** HANDLE YOUR ERRORS */
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Authorization","YOUR AUTHANTICATION TOKEN IF REQUIRED");
return params;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
return params;
}
};
restApiMultiPartRequest.setRetryPolicy(new DefaultRetryPolicy(0, 1, 2));//10000
VOLLEY_INSTANCE.addToRequestQueue(restApiMultiPartRequest);
}
这里hashmap
是HashMap<String, String> hashMap
fileparts
是 HashMap<String, File> fileparts;
所以带String
key
和String
value
的参数加入hashmap
和带有 String
键和 File
Value
的参数添加到 fileparts
我想post像这样形成数据,
其中,
- ApiKey,userid,albumid,music_name,singer_name为key对应的值都是text类型
- music_cover和music_file是图像文件和音频文件的键值。
All the values are non nullable. That is, must pass all values to the server to get a success response.
所以,总而言之,我有一堆文本、音频和图像要使用来自 android 的 Web 服务上传到服务器。
我正在使用选择器选择图像和音频,所以我有它们的文件路径。
请指导我完成使用 android 的 multipart 上传音频和图像的过程。
它让我彻夜难眠,但没有任何缓解。
这里我使用 Volley 创建了一个示例
所以首先我们必须构建一个 RestApiMultiPartRequests.class
所以我在这里创建它是这样的
私有 class RestApiMultiPartRequests 扩展请求 {
private final Map<String, String> mStringParts;
private final Map<String, File> mFileParts;
private MultipartEntityBuilder mBuilder;
private final Response.Listener<T> mListener;
public RestApiMultiPartRequests(String url,
Map<String, String> stringParts,
Map<String, File> fileParts,
Response.Listener<T> listener,
Response.ErrorListener errorListener) {
super(Method.POST, url, errorListener);
mListener = listener;
mStringParts = stringParts;
mFileParts = fileParts;
buildMultipartEntity();
}
private void buildMultipartEntity() {
if (mBuilder != null) {
mBuilder = null;
}
mBuilder = MultipartEntityBuilder.create();
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setBoundary("_____" + Long.toString(System.currentTimeMillis()) + "_____");
mBuilder.setCharset(Consts.UTF_8);
if (mStringParts != null) {
for (Map.Entry<String, String> entry : mStringParts.entrySet()) {
mBuilder.addTextBody(entry.getKey(), entry.getValue(), ContentType.create("text/plain", Charset.forName("UTF-8")));
}
}
Log.e("Size", "Size: " + mFileParts.size());
for (Map.Entry<String, File> entry : mFileParts.entrySet()) {
ContentType imageContentType = ContentType.create("image/*");//MULTIPART_FORM_DATA;
Log.d("", "Key " + entry.getKey());
Log.d("", "Value " + entry.getValue());
Log.d("", "Name " + entry.getValue().getName());
//"userfile"
mBuilder.addBinaryBody(entry.getKey(), entry.getValue(), imageContentType, entry.getValue().getName());
}
}
@Override
public String getBodyContentType() {
return mBuilder.build().getContentType().getValue();
}
@Override
public byte[] getBody() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mBuilder.build().writeTo(bos);
} catch (IOException e) {
e.printStackTrace();
}
return bos.toByteArray();
}
public HttpEntity getEntity() {
return mBuilder.build();
}
@SuppressWarnings("unchecked")
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return (Response<T>) Response.success(jsonString, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}
使用这个 class 我们可以构建这样的请求
private void UploadImage() {
ServiceCall.RestApiMultiPartRequests<String> restApiMultiPartRequest =
new ServiceCall.RestApiMultiPartRequests<String>(url/*YOUR SERVICE URL*/, hashMap /* HASHMAP OF STRING */, fileparts /*HASH MAP OF FILE AND STRING */, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
/* HANDEL YOUR SUCCESS RESPONSE **/
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Handle your error types accordingly.For Timeout & No
// connection error, you can show 'retry' button.
// For AuthFailure, you can re login with user
// credentials.
// For ClientError, 400 & 401, Errors happening on
// client side when sending api request.
// In this case you can check how client is forming the
// api and debug accordingly.
// For ServerError 5xx, you can do retry or handle
// accordingly.
/** HANDLE YOUR ERRORS */
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Authorization","YOUR AUTHANTICATION TOKEN IF REQUIRED");
return params;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
return params;
}
};
restApiMultiPartRequest.setRetryPolicy(new DefaultRetryPolicy(0, 1, 2));//10000
VOLLEY_INSTANCE.addToRequestQueue(restApiMultiPartRequest);
}
这里hashmap
是HashMap<String, String> hashMap
fileparts
是 HashMap<String, File> fileparts;
所以带String
key
和String
value
的参数加入hashmap
和带有 String
键和 File
Value
的参数添加到 fileparts