今天说一下我的图片上传方法,整体思路是自己拼写出一个html页面,然后使用post的方法将图片传到后台。
上传的执行不会在主线程中,所以我们新起一个线程,并用Handler将信息回传到主线程
private void uploadImage() {
new Thread(uploadImageRunnable).start();
//这里可以显示进度条
}
Runnable uploadImageRunnable = new Runnable() {
@Override
public void run() {
Message resultMessage = new Message();
resultMessage.what = 0;
//上传图片后回传的结果会储存在 resultMessage.obj 中
try {
//TODO 上传图片以及附加信息
} catch (Exception e) {
e.printStackTrace();
}
handler.sendMessage(resultMessage);
}
};
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case 0:
//这里可以让进度条消失
try {
//TODO 处理回传结果
} catch (Exception e) {
e.printStackTrace();
}
default:
break;
}
return false;
}
});
接下来我来说说“上传图片及附加信息”部分该如何完成
首先新建URL对象(注意这里是https,所以后面会设置SSL的相关信息)
URL url = new URL("https://......");
然后建立连接的对象
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
设置连接对象的各种属性
conn.setConnectTimeout(5000);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("ser-Agent", "Fiddler");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + MyUpLoadUtils.BOUNDARY);
MyUpLoadUtils.BOUNDARY是个分割线,这个大家可以自行寻找下html的拼写方法,这里我就不多说了,它的值如下(随意设置的)
public static final String BOUNDARY = "--my_boundary--";
HostnameVerifier hnv = new HostNameVerifier();
conn.setHostnameVerifier(hnv);
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[]{new X509TrustManagerImpl()}, null);
conn.setSSLSocketFactory(sslcontext.getSocketFactory());
HostNameVerifier 继承 AbstractVerifier,重写verify方法。
X509TrustManagerImpl 实现 javax.net.ssl.X509TrustManager接口,大家可以自己查查。
好了,设置完连接的各种属性,我们开始传输东西,首先获取输出流对象
OutputStream os = conn.getOutputStream();
DataOutputStream ds = new DataOutputStream(os);
然后开始输出,这里我用自己的方法包装了一下
MyUpLoadUtils.writeStringParams(textParams, ds);
MyUpLoadUtils.writeBytes(imageBytes, textParams.get("fileName"), ds);
MyUpLoadUtils.paramsEnd(ds);
textParams是个Map,里面有附加的一些文字信息,imageBytes是图片的二进制数组,具体方法实现如下
/**
* 普通字符串数据
*/
public static void writeStringParams(Map<String, String> textParams, DataOutputStream ds) throws Exception {
Set<String> keySet = textParams.keySet();
for (Iterator<String> it = keySet.iterator(); it.hasNext(); ) {
String name = it.next();
String value = textParams.get(name);
ds.writeBytes("--" + BOUNDARY + "\r\n");
ds.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"\r\n");
ds.writeBytes("\r\n");
value = value + "\r\n";
ds.write(value.getBytes());
}
}
/**
* 文件数据
*/
public static void writeBytes(byte[] imageBytes, String fileName, DataOutputStream ds) throws Exception {
ds.writeBytes("--" + BOUNDARY + "\r\n");
ds.writeBytes("Content-Disposition: form-data; name=\"" + "uploadFile" +
"\"; filename=\"" + fileName + "\"\r\n");
ds.writeBytes("Content-Type:application/octet-stream; charset=utf-8 \r\n");
ds.writeBytes("\r\n");
ds.write(imageBytes);
ds.writeBytes("\r\n");
}
/**
* 添加结尾数据
*/
public static void paramsEnd(DataOutputStream ds) throws Exception {
ds.writeBytes("--" + BOUNDARY + "--" + "\r\n");
ds.writeBytes("\r\n");
}
别忘记关闭输出流对象
os.close();
然后我们获取服务器的响应信息
int code = conn.getResponseCode();
if (code == 200) {// 返回的响应码200,是成功
// 得到网络返回的输入流
InputStream is = conn.getInputStream();
resultMessage.obj = MyUpLoadUtils.readString(is);
} else {
ToastUtils.show("请求URL失败!");
}
readString方法如下:
public static String readString(InputStream is) {
byte[] result = readBytes(is);
if(result != null){
return new String(result);
}else{
return "";
}
}
private static byte[] readBytes(InputStream is) {
try {
byte[] buffer = new byte[1024];
int len = -1;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
baos.close();
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
以上是“上传图片及附加信息”部分,放在try{}catch中,最后我们把回传的信息通过Handler传入主线程中
handler.sendMessage(resultMessage);
最后,在主线程中用Gosn解析,处理回传结果
String result = (String) msg.obj;
Log.e(TAG, result);
JSONObject jsonObject = new JSONObject(result);
Gson gson = new Gson();
XXXXX item = gson.fromJson(result, XXXXX.class);
//TODO 处理回传信息
以上就是我的上传图片方法。