package com.cn.jiayuanshu.cd.android.parents.task;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.cn.jiayuanshu.cd.android.parents.util.ServerConfig;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
/*
* 2014年12月20日23:03:29
* function:模拟实现表单式上传图片并得到其在服务器的地址(该地址和其它注册信息利用普通的网络请求提交给服务器)
* 说明:android中的File无法获取文件格式,需要上传其它类型文件需要修改(line 162) Content-Type: image/jpeg
* author:JiangHong
*/
public class UpFileTask extends AsyncTask<String, Integer, List<String>> {
public static final String LOG="UpFileTask";
/*
* 背景:提交注册信息时要上传图片
* 方式:先上传图片到服务器得到图片在服务器的地址,再将地址和其它基本数据一起上传进行二次
* 问题:服务器实现的是表单上传文件,但是Android的 ApacheHTTP不支持表单形式上传文件,必须另类实现
* function:表单方式上传文件(这里只支持图片) 将这种形式的String写入一个Output上传即可
*
* --****************
* Content-Disposition: form-data; name="upload_file"; filename="apple.jpg"
* Content-Type: image/jpeg
* 必须空一行
* 文件内容(二进制流)
*/
private String multipart_form_data = "multipart/form-data";
private String twoHyphens = "--";
private String boundary = "****************";// 数据分隔符
private String lineEnd = System.getProperty("line.separator"); // The value is "\r\n" in Windows.(换行符)
private HttpURLConnection conn;
private String url;
private DataOutputStream output;
private BufferedReader input;
private Context context;
private List<File> images;//(支持多文件上传)
private boolean isSuccess;//是否上传成功
private List<String> get;
private Handler handler;
public UpFileTask(Context context,List<File> images,Handler handler){
this.url=ServerConfig.UPIMAGE;
Log.i(LOG, url);
this.context=context;
this.images=images;
this.handler=handler;
}
@Override
protected List<String> doInBackground(String... params) {
isSuccess=false;
try {
URL urls=new URL(this.url);
conn=(HttpURLConnection) urls.openConnection();
conn.setConnectTimeout(8*1000);//8秒超时
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "keep-alive");
//表单形式上传图片(很重要)
conn.setRequestProperty("Content-Type", multipart_form_data+";boundary="+boundary);
conn.connect();//打开链接
//很重要(数据封装到这里上传)
output=new DataOutputStream(conn.getOutputStream());
addFiles(this.images, output);//此处还可添加普通字段一起上传
output.writeBytes(twoHyphens+boundary+twoHyphens+lineEnd);//数据结束标志
output.flush();
//获取返回信息
if(conn.getResponseCode()==200){//成功
input=new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer data=new StringBuffer();
String line;
while((line=input.readLine())!=null){
data.append(line+lineEnd);
}
//至此得到返回的JSON数据data
getUrlData(data.toString());
}
if(conn!=null){
conn.disconnect();//关闭链接
}
} catch (MalformedURLException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
if(isSuccess){
return get;
}
return null;
}
@Override
protected void onPostExecute(List<String> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(result!=null){//成功上传图片并得到反馈的地址
//将该地址和其它注册信息上传
android.os.Message msg=this.handler.obtainMessage();
msg.what=103;
msg.obj=get;
this.handler.sendMessage(msg);
}else{//上传图片失败
this.handler.sendEmptyMessage(104);
}
this.handler=null;
}
/*
* 背景:提交注册信息时要上传图片
* 方式:先上传图片到服务器得到图片地址,再将图片地址和其它基本数据一起上传
* 问题:服务器实现的是表单上传文件,但是Android的 ApacheHTTP不支持表单形式上传文件,必须另类实现
* function:表单方式上传文件(这里只支持图片) 利用网络上传output即可
*
* --****************
* Content-Disposition: form-data; name="upload_file"; filename="apple.jpg"
* Content-Type: image/jpeg
* 必须空一行
* 文件内容(二进制流)
*/
private void addFiles(List<File> files,DataOutputStream output){
StringBuffer spilt;
for(File file:files){
spilt=new StringBuffer();
spilt.append(twoHyphens+boundary+lineEnd);
spilt.append("Content-Disposition: form-data; name=\"Updata\";filename=\" "+file.getName()+" \" "+lineEnd);
spilt.append("Content-Type: image/jpeg" + lineEnd);
spilt.append(lineEnd);
// 发送图片数据
try {
output.writeBytes(spilt.toString());
output.write(fileToBytes(file), 0, (int) file.length());
output.writeBytes(lineEnd);
} catch (IOException e) {
e.printStackTrace();
}
}
}
//将File转为二进制流
private byte[] fileToBytes(File file){
byte[] data=new byte[(int) file.length()];
try {
InputStream in = new FileInputStream(file);
in.read(data);
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
return data;
}
//解析JSON(这里根据服务器具体来解析)
private void getUrlData(String json){
try {
JSONObject data=new JSONObject(json);
boolean success=data.getBoolean("Success");
if(success){
JSONArray da=data.getJSONArray("Data");
if(da!=null){
Log.i(LOG, da.toString());
get=null;
get=new ArrayList<String>();
for(int i=0;i<da.length();i++){
get.add(da.getString(i));
}
isSuccess=true;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}