项目中访问网络的框架使用的是volley,有上传照片的需求,刚开始上传成功,后来加入参数,不成功,最后将图片转换为base64,作为参数上传,算是暂时解决了问题,今天在网上看到几篇上传图片的文章,试了一下,上传成功,记录一下
请求类
package com.android.volley.toolbox;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
import com.common.utils.CLog;
import com.common.utils.FileUtil;
public class MultipartRequest extends Request<String> {
private MultipartEntity entity = new MultipartEntity();
private final Response.Listener<String> mListener;
private List<File> mFileParts;
private String mFilePartName;
private Map<String, String> mParams;
/**
* 单个文件
* @param url
* @param errorListener
* @param listener
* @param filePartName
* @param file
* @param params
*/
public MultipartRequest(String url, Response.ErrorListener errorListener,
Response.Listener<String> listener, String filePartName, File file,
Map<String, String> params) {
super(Method.POST, url, errorListener);
mFileParts = new ArrayList<File>();
if (file != null) {
mFileParts.add(file);
}
mFilePartName = filePartName;
mListener = listener;
mParams = params;
buildMultipartEntity();
}
/**
* 多个文件,对应一个key
* @param url
* @param errorListener
* @param listener
* @param filePartName
* @param files
* @param params
*/
public MultipartRequest(String url, Response.ErrorListener errorListener,
Response.Listener<String> listener, String filePartName,
List<File> files, Map<String, String> params) {
super(Method.POST, url, errorListener);
mFilePartName = filePartName;
mListener = listener;
mFileParts = files;
mParams = params;
buildMultipartEntity();
}
private void buildMultipartEntity() {
if (mFileParts != null && mFileParts.size() > 0) {
for (File file : mFileParts) {
entity.addPart(mFilePartName, new FileBody(file));
}
long l = entity.getContentLength();
CLog.log(mFileParts.size()+"个,长度:"+l);
}
try {
if (mParams != null && mParams.size() > 0) {
for (Map.Entry<String, String> entry : mParams.entrySet()) {
entity.addPart(
entry.getKey(),
new StringBody(entry.getValue(), Charset
.forName("UTF-8")));
}
}
} catch (UnsupportedEncodingException e) {
VolleyLog.e("UnsupportedEncodingException");
}
}
@Override
public String getBodyContentType() {
return entity.getContentType().getValue();
}
@Override
public byte[] getBody() throws AuthFailureError {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
entity.writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
CLog.log("parseNetworkResponse");
if (VolleyLog.DEBUG) {
if (response.headers != null) {
for (Map.Entry<String, String> entry : response.headers
.entrySet()) {
VolleyLog.d(entry.getKey() + "=" + entry.getValue());
}
}
}
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));
}
/*
* (non-Javadoc)
*
* @see com.android.volley.Request#getHeaders()
*/
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
VolleyLog.d("getHeaders");
Map<String, String> headers = super.getHeaders();
if (headers == null || headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
return headers;
}
@Override
protected void deliverResponse(String response) {
mListener.onResponse(response);
}
}
访问https的volley单例类
public class VolleySingleton {
private static VolleySingleton volleySingleton;
private RequestQueue mRequestQueue;
private Context mContext;
public VolleySingleton(Context context) {
this.mContext = context;
mRequestQueue = getRequestQueue();
}
public static synchronized VolleySingleton getVolleySingleton(Context context){
if(volleySingleton == null){
volleySingleton = new VolleySingleton(context);
}
return volleySingleton;
}
public RequestQueue getRequestQueue(){
if(mRequestQueue == null){
InputStream keyStore =mContext.getResources().openRawResource(R.raw.server);
mRequestQueue = Volley
.newRequestQueue(mContext,
new ExtHttpClientStack(new SslHttpClient(keyStore, "123456", 8444)));
//mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
}
return mRequestQueue;
}
}
调用方法
try {
String path = Environment
.getExternalStorageDirectory() + "/" + IMAGE_SCROP_FILE_NAME;
final Bitmap bitmap =
new LoadBigImage().decodeSampledBitmapFromByte(getBytesFromInputStream(new FileInputStream(path)), 150, 150);
String url = StaticParameter.interfaceUrl + "uploadUrl";
Map<String, String> params = new HashMap<String, String>();
params.put("userId", StaticParameter.userId);
File f1 = new File(path);
// File f2 = new File(path);
if (!f1.exists()) {
Toast.makeText(getApplicationContext(), "图片不存在", Toast.LENGTH_SHORT).show();
return;
}
final CustomProgressDialog dialog = new CustomProgressDialog(PersonCenterActivity.this);
final MultipartRequestForUploadFiles requestForUploadFiles = new MultipartRequestForUploadFiles(url, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
L.e("uploaderror" + error);
T.showShort(PersonCenterActivity.this, "上传失败");
}
}, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
L.e("uploadresponse" + response);
try {
Gson gson = new Gson();
BaseJson baseJson = gson.fromJson(response, BaseJson.class);
String code = baseJson.getCode() + "";
String token = baseJson.getToken();
String message = baseJson.getMessage();
if (code.equals("0")) {
imageViewHead.setImageBitmap(bitmap);
T.showShort(PersonCenterActivity.this, "上传成功");
} else {
T.showShort(PersonCenterActivity.this, message);
}
dialog.hideDialog();
} catch (Exception e) {
e.printStackTrace();
dialog.hideDialog();
T.showLong(PersonCenterActivity.this, "数据解析出错");
}
}
}, "f_file[]", f1, params);
dialog.showMyDialog();
dialog.setmListener(new CustomProgressDialog.customProgressDialogInterface() {
@Override
public void dismissDoSomething() {
try {
requestForUploadFiles.cancel();
} catch (Exception e) {
e.printStackTrace();
}
}
});
RequestQueue mRequestQueue = VolleySingleton.getVolleySingleton(PersonCenterActivity.this).getRequestQueue();
mRequestQueue.add(requestForUploadFiles);
}catch (Exception e){
e.printStackTrace();
}
CustomProgressDialog为自定义加载控件
/**
* Created by Administrator on 2016/2/25 0025.
* 自定义加载对话框
*/
public class CustomProgressDialog {
private Context mContext;
private Dialog dialog;
private customProgressDialogInterface mListener;
public CustomProgressDialog(Context context){
mContext = context;
dialog = new Dialog(mContext, R.style.alert_dialog);
}
public void showMyDialog(){
View view = View.inflate(mContext, R.layout.dialog_progress,null);
dialog.setContentView(view);
try{
dialog.show();
}catch (Exception e){
e.printStackTrace();
}
}
public void hideDialog(){
if(dialog!=null){
dialog.dismiss();
}
dialog=null;
if(mListener!=null){
mListener.dismissDoSomething();
}
}
public void setmListener(customProgressDialogInterface mListener) {
this.mListener = mListener;
}
public interface customProgressDialogInterface{
public void dismissDoSomething();//对话框消失的时候做的操作,跳转之类
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/bg"
android:padding="20dp">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
参考文章:
Android 使用volley上传图片、多张图片
服务器基于PHP CodeIgniter,Android基于Volley实现多文件/图片上传(含服务器,web版和android客户端完整代码)
测试使用volley同时上传参数和文件(包含多文件)