public class MainApplication extends Application {
	
	public static final String APP_KEY = "YOUR-APP_KEY ";
	
	public static final String APP_SECRET = "YOUR-APP_SECRET ";
	
	public static final Client CLIENT = new Client(APP_KEY, APP_SECRET);
	
	public static String APP_ROOT_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/FaceDemo/";
	
	public static String APP_PIC_PATH = APP_ROOT_DIR + "image/";
	
	public static String USER_NAME = "xiaoying";
	
	public static int mScreenWidth = 0;

	@Override
	public void onCreate() {
		super.onCreate();
		
		File file = new File(APP_ROOT_DIR);
		if(!file.exists()) {
			file.mkdirs();
		}
		
		file = new File(APP_PIC_PATH);
		if(!file.exists()) {
			file.mkdirs();
		}
	}
} public class GroupListAdapter extends BaseAdapter {
	
	private Context mContext = null;
	
	private List<Group> mGroups = new ArrayList<Group>();
	
	private List<Boolean> mChecked = new ArrayList<Boolean>();
	
	private int mMode = PersonListActivity.MODE_VIEW;
	
	public GroupListAdapter(Context context) {
		this.mContext = context;
	}
	
	public GroupListAdapter(Context context, int mode) {
		this.mContext = context;
		this.mMode = mode;
	}
	
	public void add(Group group) {
		mGroups.add(group);
		mChecked.add(false);
		notifyDataSetChanged();
	}
	
	public void add(int position, Group group) {
		mGroups.add(position, group);
		mChecked.add(position, false);
		notifyDataSetChanged();
	}
	
	
	public void addAll(List<Group> groups) {
		mGroups.addAll(groups);
		for (int i = 0; i < groups.size(); i++) {
			mChecked.add(false);
		}
		notifyDataSetChanged();
	}
	
	public void remove(int position) {
		mGroups.remove(position);
		mChecked.remove(position);
		notifyDataSetChanged();
	}
	
	public void replace(int position, Group group) {
		mGroups.remove(position);
		mGroups.add(position, group);
		notifyDataSetChanged();
	}
	
	public void clear() {
		mGroups.clear();
		mChecked.clear();
		notifyDataSetChanged();
	}
	
	public void setChecked(int position, boolean isChecked) {
		mChecked.remove(position);
		mChecked.add(position, isChecked);
		notifyDataSetChanged();
	}
	
	public boolean isChecked(int position) {
		return mChecked.get(position);
	}
	
	public List<Group> getCheckedItems() {
		List<Group> selectedItems = new ArrayList<Group>();
		for (int i = 0; i < mChecked.size(); i++) {
			if(mChecked.get(i)) {
				selectedItems.add(mGroups.get(i));
			}
		}
		return selectedItems;
	}

	@Override
	public int getCount() {
		return mGroups.size();
	}

	@Override
	public Group getItem(int position) {
		return mGroups.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHoder viewHoder = null;
		if(convertView == null) {
			viewHoder = new ViewHoder();
			convertView = View.inflate(mContext, R.layout.item_list, null);
			viewHoder.icon = (ImageView) convertView.findViewById(R.id.iv_item_icon);
			viewHoder.text1 = (TextView) convertView.findViewById(R.id.tv_item_text1);
			viewHoder.text2 = (TextView) convertView.findViewById(R.id.tv_item_text2);
			viewHoder.text3 = (TextView) convertView.findViewById(R.id.tv_item_text3);
			viewHoder.check = (CheckBox) convertView.findViewById(R.id.cb_item_checked);
			convertView.setTag(viewHoder);
		} else {
			viewHoder = (ViewHoder) convertView.getTag();
		}
		Group group = getItem(position);
		viewHoder.icon.setImageResource(R.drawable.ic_launcher);
		viewHoder.text1.setText(group.getGroup_name());
		viewHoder.text2.setText(group.getGroup_id());
		viewHoder.text3.setText(group.getTag());
		if(mMode == PersonListActivity.MODE_CHOOSE) {
			viewHoder.check.setVisibility(View.VISIBLE);
			viewHoder.check.setChecked(mChecked.get(position));
		} else {
			viewHoder.check.setVisibility(View.GONE);
		}
		return convertView;
	}

	private static class ViewHoder {
		ImageView icon;
		TextView text1;
		TextView text2;
		TextView text3;
		CheckBox check;
	}
} public class LogUtil {

	private final static boolean isPrint = true;
	
	public static void i(String tag, String msg) {
		if(isPrint) {
			Log.i(tag, msg);
		}
	}
	
	public static void i(String tag, Object msg) {
		if(isPrint) {
			Log.i(tag, msg.toString());
		}
	}
	
	public static void w(String tag, String msg) {
		if(isPrint) {
			Log.w(tag, msg);
		}
	}

	public static void w(String tag, Object msg) {
		if(isPrint) {
			Log.w(tag, msg.toString());
		}
	}
	
	public static void e(String tag, String msg) {
		if(isPrint) {
			Log.e(tag, msg);
		}
	}

	public static void e(String tag, Object msg) {
		if(isPrint) {
			Log.e(tag, msg.toString());
		}
	}
} public class TitleBar extends RelativeLayout {
	
	private Button mBtnLeft = null;
	
	private TextView mTvCenter = null;
	
	private Button mBtnRight = null;
	
	public TitleBar(Context context) {
		super(context);
		initView(context);
	}

	public TitleBar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initView(context);
	}

	public TitleBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}

	private void initView(Context context) {
		View view = View.inflate(context, R.layout.layout_top_title, null);
		mBtnLeft = (Button) view.findViewById(R.id.btn_top_left);
		mTvCenter = (TextView) view.findViewById(R.id.tv_top_center);
		mBtnRight = (Button) view.findViewById(R.id.btn_top_right);
		addView(view, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
	}
	
	
	public void setTitle(CharSequence text) {
		mTvCenter.setText(text);
	}
	
	public void setTitle(int resid) {
		mTvCenter.setText(resid);
	}
	
	public void setLeftButtonText(CharSequence text) {
		mBtnLeft.setText(text);
	}
	
	public void setLeftButtonText(int resid) {
		mBtnLeft.setText(resid);
	}
	
	public void setLeftButtonIcon(int resid) {
		mBtnLeft.setBackgroundResource(resid);
	}
	
	public void setLeftButtonListener(View.OnClickListener listener) {
		mBtnLeft.setOnClickListener(listener);
	}
	
	public void setLeftButton(CharSequence text, View.OnClickListener listener) {
		setLeftButtonText(text);
		setLeftButtonListener(listener);
	}
	
	public void setLeftButton(int resid, View.OnClickListener listener) {
		setLeftButtonText(resid);
		setLeftButtonListener(listener);
	}

	public void setRightButtonText(CharSequence text) {
		mBtnRight.setText(text);
	}
	
	public void setRightButtonText(int resid) {
		mBtnRight.setText(resid);
	}
	
	public void setRightButtonIcon(int resid) {
		mBtnRight.setBackgroundResource(resid);
	}
	
	public void setRightButtonListener(View.OnClickListener listener) {
		mBtnRight.setOnClickListener(listener);
	}
	
	public void setRightButton(CharSequence text, View.OnClickListener listener) {
		setRightButtonText(text);
		setRightButtonListener(listener);
	}
	
	public void setRightButton(int resid, View.OnClickListener listener) {
		setRightButtonText(resid);
		setRightButtonListener(listener);
	}
	
	public void setLeftButtonVisible(boolean isVisible) {
		mBtnLeft.setVisibility(isVisible ? View.VISIBLE : View.INVISIBLE);
	}
	
	public void setRightButtonVisible(boolean isVisible) {
		mBtnRight.setVisibility(isVisible ? View.VISIBLE : View.INVISIBLE);
	}
	
} public class RespConfig {

	public final static int RESP_OK = 0;
	
	public final static int FACESET_MAX_FACE = 10000;
	
} public class Group implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -5604871764437501922L;
	private String group_id;	//相应group的id
	private String group_name;	//相应group的name
	private String tag;	//group相关的tag
	private int person_count;	//Group包含的Person个数
	private List<Person> person;	//属于该group的person信息
	
	/**
	 * 相应group的id
	 * @return
	 */
	public String getGroup_id() {
		return group_id;
	}
	
	/**
	 * 相应group的id
	 * @param group_id
	 */
	public void setGroup_id(String group_id) {
		this.group_id = group_id;
	}
	
	/**
	 * 相应group的name
	 * @return
	 */
	public String getGroup_name() {
		return group_name;
	}
	
	/**
	 * 相应group的name
	 * @param group_name
	 */
	public void setGroup_name(String group_name) {
		this.group_name = group_name;
	}
	
	/**
	 * group相关的tag
	 * @return
	 */
	public String getTag() {
		return tag;
	}
	
	/**
	 * group相关的tag
	 * @param tag
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}
	
	/**
	 * 
	 * @return the person_count
	 */
	public int getPerson_count() {
		return person_count;
	}

	/**
	 * 
	 * @param person_count the person_count to set
	 */
	public void setPerson_count(int person_count) {
		this.person_count = person_count;
	}

	/**
	 * 属于该group的person信息
	 * @return
	 */
	public List<Person> getPerson() {
		return person;
	}
	
	/**
	 * 属于该group的person信息
	 * @param person
	 */
	public void setPerson(List<Person> person) {
		this.person = person;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Group [group_id=" + group_id + ", group_name=" + group_name
				+ ", tag=" + tag + ", person_count=" + person_count
				+ ", person=" + person + ", getClass()=" + getClass()
				+ ", hashCode()=" + hashCode() + ", toString()="
				+ super.toString() + "]";
	}
} public class GroupDeleteReq extends BaseRequest {
	private String group_name;	//一组用逗号分割的group_id，表示删除这些Group
	private String group_id;	//一组用逗号分割的group_name，表示删除这些Group
	
 	public GroupDeleteReq() {
		
	}
	
	public GroupDeleteReq(String group, boolean isId) {
		if(isId) {
			setGroup_id(group);
		} else {
			setGroup_name(group);
		}
	}
	
	/**
	 * 一组用逗号分割的group_name，表示删除这些Group
	 * 
	 * @return
	 */
	public String getGroup_name() {
		return group_name;
	}
	
	/**
	 * 一组用逗号分割的group_name，表示删除这些Group
	 * 与setGroup_id(String group_id)只能选其一
	 * @param group_name
	 */
	public void setGroup_name(String group_name) {
		this.group_name = group_name;
		this.group_id = null;
	}
	
	/**
	 * 一组用逗号分割的group_id，表示删除这些Group
	 * @return
	 */
	public String getGroup_id() {
		return group_id;
	}
	
	/**
	 * 一组用逗号分割的group_id，表示删除这些Group
	 * 与setGroup_id(String group_id)只能选其一
	 * @param group_id
	 */
	public void setGroup_id(String group_id) {
		this.group_id = group_id;
		this.group_name = null;
	}
	
	@Override
	public String toString() {
		return "GroupDeleteReq [group_name=" + group_name + ", group_id="
				+ group_id + "]";
	}
} public class GroupDeleteResp extends BaseResponse {
	private int deleted;	//成功删除的group数量
	private boolean success;	//表示操作是否成功
	
	/**
	 * 成功删除的group数量
	 * @return
	 */
	public int getDeleted() {
		return deleted;
	}
	
	/**
	 * 成功删除的group数量
	 * @param deleted
	 */
	public void setDeleted(int deleted) {
		this.deleted = deleted;
	}
	
	/**
	 * 表示操作是否成功
	 * @return
	 */
	public boolean isSuccess() {
		return success;
	}
	
	/**
	 * 表示操作是否成功
	 * @param success
	 */
	public void setSuccess(boolean success) {
		this.success = success;
	}

	@Override
	public String toString() {
		return "GroupDeleteResp [deleted=" + deleted + ", success=" + success
				+ ", error=" + error + ", error_code=" + error_code + "]";
	}
} public class InfoGetGroupListResp extends BaseResponse {

	private List<Group> group;	//Group列表

	/**
	 * Group列表
	 * @return the group
	 */
	public List<Group> getGroup() {
		return group;
	}

	/**
	 * Group列表
	 * @param group the group to set
	 */
	public void setGroup(List<Group> group) {
		this.group = group;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "InfoGetGroupListResp [group=" + group + ", error=" + error
				+ ", error_code=" + error_code + "]";
	}
} public class GroupService extends BaseService {

	public GroupService(Client client) {
		super(client);
	}

	/**
	 * 创建Group
	 * @param body
	 * @return
	 * @throws IOException 
	 * @throws ClientProtocolException 
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public GroupCreateResp createGroup(GroupCreateReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("group_name", body.getGroup_name());
		params.put("tag", body.getTag());
		params.put("person_id", body.getPerson_id());
		params.put("person_name", body.getPerson_name());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_GROUP_CREATE, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		GroupCreateResp result = new GroupCreateResp();
		result.setGroup_id(json.optString("group_id"));
		result.setGroup_name(json.optString("group_name"));
		result.setTag(json.optString("tag"));
		result.setAdded_person(json.optInt("added_person"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}
	
	/**
	 * 删除Group
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public GroupDeleteResp deleteGroup(GroupDeleteReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getGroup_id()) && StringUtil.isEmpty(body.getGroup_name())) {
			throw new IllegalArgumentException("group_id or group_name must to be set one");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("group_name", body.getGroup_name());
		params.put("group_id", body.getGroup_id());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_GROUP_DELETE, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		GroupDeleteResp result = new GroupDeleteResp();
		result.setSuccess(json.optBoolean("success"));
		result.setDeleted(json.optInt("deleted"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}
	
	/**
	 * 添加Person
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public GroupAddPersonResp addPerson(GroupAddPersonReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getGroup_id()) && StringUtil.isEmpty(body.getGroup_name())) {
			throw new IllegalArgumentException("group_id or group_name must to be set one");
		}
		if(StringUtil.isEmpty(body.getPerson_id()) && StringUtil.isEmpty(body.getPerson_name())) {
			throw new IllegalArgumentException("person_id or person_name must to be set one");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("group_name", body.getGroup_name());
		params.put("group_id", body.getGroup_id());
		params.put("person_name", body.getPerson_name());
		params.put("person_id", body.getPerson_id());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_GROUP_ADD_PERSON, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		GroupAddPersonResp result = new GroupAddPersonResp();
		result.setSuccess(json.optBoolean("success"));
		result.setAdded(json.optInt("added"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 从Group中删除Person
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public GroupRemovePersonResp removePerson(GroupRemovePersonReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getGroup_id()) && StringUtil.isEmpty(body.getGroup_name())) {
			throw new IllegalArgumentException("group_id or group_name must to be set one");
		}
		if(StringUtil.isEmpty(body.getPerson_id()) && StringUtil.isEmpty(body.getPerson_name())) {
			throw new IllegalArgumentException("person_id or person_name must to be set one");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("group_name", body.getGroup_name());
		params.put("group_id", body.getGroup_id());
		params.put("person_name", body.getPerson_name());
		params.put("person_id", body.getPerson_id());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_GROUP_ADD_PERSON, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		GroupRemovePersonResp result = new GroupRemovePersonResp();
		result.setSuccess(json.optBoolean("success"));
		result.setRemoved(json.optInt("removed"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}
	
	/**
	 * 设置Group的信息
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public GroupSetInfoResp setGroupInfo(GroupSetInfoReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getGroup_id()) && StringUtil.isEmpty(body.getGroup_name())) {
			throw new IllegalArgumentException("group_id or group_name must to be set one");
		}
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("group_name", body.getGroup_name());
		params.put("group_id", body.getGroup_id());
		params.put("name", body.getName());
		params.put("tag", body.getTag());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_GROUP_SET_INFO, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		GroupSetInfoResp result = new GroupSetInfoResp();
		result.setGroup_name(json.optString("group_name"));
		result.setGroup_id(json.optString("group_id"));
		result.setTag(json.optString("tag"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	public GroupGetInfoResp getGroupInfo(GroupGetInfoReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getGroup_id()) && StringUtil.isEmpty(body.getGroup_name())) {
			throw new IllegalArgumentException("group_id or group_name must to be set one");
		}
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("group_name", body.getGroup_name());
		params.put("group_id", body.getGroup_id());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_GROUP_GET_INFO, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		GroupGetInfoResp result = new GroupGetInfoResp();
		result.setGroup_name(json.optString("group_name"));
		result.setGroup_id(json.optString("group_id"));
		result.setTag(json.optString("tag"));
		result.setPerson(getPersons(json.optJSONArray("person")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}
	
	private List<Person> getPersons(JSONArray personArray) {
		List<Person> persons = new ArrayList<Person>();
		if(personArray != null) {
			Person person = null;
			JSONObject personObj = null;
			for(int i = 0; i < personArray.length(); i++) {
				personObj = personArray.optJSONObject(i);
				person = new Person();
				person.setPerson_name(personObj.optString("person_name"));
				person.setPerson_id(personObj.optString("person_id"));
				person.setTag(personObj.optString("tag"));
				persons.add(person);
			}
		}
		return persons;
	}
	
} public class InfoService extends BaseService {

	/**
	 * @param client
	 */
	public InfoService(Client client) {
		super(client);
	}
	
	/**
	 * 获取一张image的信息, 包括其中包含的face等信息
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetImageResp getImage(InfoGetImageReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getImg_id())) {
			throw new IllegalArgumentException("img_id should not be null");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("img_id", body.getImg_id());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_IMAGE, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetImageResp result = new InfoGetImageResp();
		result.setImg_id(json.optString("img_id"));
		result.setUrl(json.optString("url"));
		result.setFace(getFaces(json.optJSONArray("face")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 给定一组Face，返回相应的信息(包括源图片, 相关的person等等)。
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetFaceResp getFace(InfoGetFaceReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getFace_id())) {
			throw new IllegalArgumentException("img_id should not be null");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("face_id", body.getFace_id());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_FACE, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetFaceResp result = new InfoGetFaceResp();
		result.setFace_info(getFaceInfo(json.optJSONArray("face_info")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 返回该App中的所有Person
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetPersonListResp getPersonList() throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_PERSON_LIST, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetPersonListResp result = new InfoGetPersonListResp();
		result.setPerson(getPersons(json.optJSONArray("person")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 返回该App中的所有faceset
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetFacesetListResp getFacsetList() throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_FACESET_LIST, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetFacesetListResp result = new InfoGetFacesetListResp();
		result.setFaceset(getFacesets(json.optJSONArray("faceset")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}
	
	/**
	 * 返回这个App中的所有Group
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetGroupListResp getGroupList() throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_GROUP_LIST, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetGroupListResp result = new InfoGetGroupListResp();
		result.setGroup(getGroups(json.optJSONArray("group")));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 查获取session相关状态和结果
	 *
	 * 可能的status：INQUEUE(队列中), SUCC(成功) 和FAILED(失败)
	 * 当status是SUCC时，返回结果中还包含session对应的结果
	 * 所有session都将在计算完成72小时之后过期，并被自动清除。
	 * status返回值为SUCC仅表示成功取得运行结果，实际任务成功与否请根据result内容判断
	 * @param sessionId
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetSessionResp getSesson(String sessionId) throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("session_id", sessionId);
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_SESSION, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetSessionResp result = new InfoGetSessionResp();
		result.setSession_id(json.optString("session_id"));
		result.setCreate_time(json.optInt("create_time"));
		result.setFinish_time(json.optInt("finish_time"));
		result.setStatus(json.optString("status"));
		result.setResult(json.optJSONObject("result"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 查询Quota使用情况简报
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetQuotaResp getQuota() throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_QUOTA, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetQuotaResp result = new InfoGetQuotaResp();
		result.setTotal(json.optInt("total"));
		result.setUsed(json.optInt("used"));
		result.setExceed(json.optInt("exceed"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}

	/**
	 * 获取该App相关的信息
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public InfoGetAppResp getApp() throws ClientProtocolException, IOException, ParseException, JSONException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_INFO_GET_APP, params);
		JSONObject json = new JSONObject(EntityUtils.toString(resp.getEntity()));
		Log.i(json.toString());
		InfoGetAppResp result = new InfoGetAppResp();
		result.setName(json.optString("name"));
		result.setDescription(json.optString("description"));
		result.setError(json.optString("error"));
		result.setError_code(json.optInt("error_code", RespConfig.RESP_OK));
		return result;
	}
	
	
	/**
	 * 解析JSONArray中的FaceInfo
	 * @param faceInfoArray
	 * @return
	 */
	private List<FaceInfo> getFaceInfo(JSONArray faceInfoArray) {
		List<FaceInfo> faceInfos = new ArrayList<FaceInfo>();
		if(faceInfoArray != null) {
			JSONObject faceInfoObj = null;
			FaceInfo faceInfo = null;
			Face face = null;
			for(int i = 0; i < faceInfoArray.length(); i++) {
				faceInfoObj = faceInfoArray.optJSONObject(i);
				faceInfo = new FaceInfo();
				face = new Face();
//				faceInfo.setFace_id(faceInfoObj.optString("face_id"));
//				faceInfo.setImg_id(faceInfoObj.optString("img_id"));
//				faceInfo.setUrl(faceInfoObj.optString("url"));
//				faceInfo.setTag(faceInfoObj.optString("tag"));
				face.setFace_id(faceInfoObj.optString("face_id"));
				face.setImg_id(faceInfoObj.optString("img_id"));
				face.setUrl(faceInfoObj.optString("url"));
				face.setTag(faceInfoObj.optString("tag"));
				FaceService.setAttribute(faceInfoObj.optJSONObject("attribute"), face);
				FaceService.setPosition(faceInfoObj.optJSONObject("position"), face);
//				faceInfo.setAttribute(getAttribute(faceInfoObj.optJSONObject("attribute")));
//				faceInfo.setPosition(FaceService.getPosition(faceInfoObj.optJSONObject("position")));
				faceInfo.setPerson(getPersons(faceInfoObj.optJSONArray("person")));
				faceInfo.setFaceset(getFacesets(faceInfoObj.optJSONArray("faceset")));
				faceInfos.add(faceInfo);
			}
		}
		return faceInfos;
	}
	
	/**
	 * 解析JSONArray中的Face
	 * @param faceArray
	 * @return
	 */
	private List<Face> getFaces(JSONArray faceArray) {
		List<Face> faces = new ArrayList<Face>();
		if(faceArray != null) {
			JSONObject faceObj = null;
			Face face = null;
			for(int i = 0; i < faceArray.length(); i++) {
				faceObj = faceArray.optJSONObject(i);
				face = new Face();
				face.setFace_id(faceObj.optString("face_id"));
				face.setTag(faceObj.optString("tag"));
				FaceService.setPosition(faceObj.optJSONObject("position"), face);
//				face.setPosition(FaceService.getPosition(faceObj.optJSONObject("position")));
				faces.add(face);
			}
		}
		return faces;
	}

	/**
	 * 解析JSONArray中的Faceset
	 * @param facesetArray
	 * @return
	 */
	private List<Faceset> getFacesets(JSONArray facesetArray) {
		List<Faceset> facesets = new ArrayList<Faceset>();
		if(facesetArray != null) {
			JSONObject facesetObj = null;
			Faceset faceset = null;
			for(int i = 0; i < facesetArray.length(); i++) {
				facesetObj = facesetArray.optJSONObject(i);
				faceset = new Faceset();
				faceset.setFaceset_id(facesetObj.optString("faceset_id"));
				faceset.setFaceset_name(facesetObj.optString("faceset_name"));
				faceset.setTag(facesetObj.optString("tag"));
				facesets.add(faceset);
			}
		}
		return facesets;
	}
	
	/**
	 * 解析JSONArray中的Person
	 * @param personArray
	 * @return
	 */
	private List<Person> getPersons(JSONArray personArray) {
		List<Person> persons = new ArrayList<Person>();
		if(personArray != null) {
			JSONObject personObj = null;
			Person person = null;
			for(int i = 0; i < personArray.length(); i++) {
				personObj = personArray.optJSONObject(i);
				person = new Person();
				person.setPerson_id(personObj.optString("person_id"));
				person.setPerson_name(personObj.optString("person_name"));
				person.setTag(personObj.optString("tag"));
				persons.add(person);
		}
		}
		return persons;
	}

	/**
	 * 解析JSONArray中的Group
	 * @param groupArray
	 * @return
	 */
	private List<Group> getGroups(JSONArray groupArray) {
		List<Group> groups = new ArrayList<Group>();
		if(groupArray != null) {
			JSONObject groupObj = null;
			Group group = null;
			for(int i = 0; i < groupArray.length(); i++) {
				groupObj = groupArray.optJSONObject(i);
				group = new Group();
				group.setGroup_id(groupObj.optString("group_id"));
				group.setGroup_name(groupObj.optString("group_name"));
				group.setTag(groupObj.optString("tag"));
				groups.add(group);
			}
		}
		return groups;
	}

//	/**
//	 * 解析JSONArray中的Face.Attribute
//	 * @param attributeObj
//	 * @return
//	 */
//	private Face.Attribute getAttribute(JSONObject attributeObj) {
//		Face.Attribute attribute = new Face.Attribute();
//		JSONObject ageObj = attributeObj.optJSONObject("age");
//		Face.Age age = new Face.Age();
//		age.setValue(ageObj.optInt("value"));
//		age.setRange(ageObj.optInt("range"));
//		attribute.setAge(age);
//		JSONObject genderObj = attributeObj.optJSONObject("gender");
//		Face.Gender gender = new Face.Gender();
//		gender.setValue(genderObj.optString("value"));
//		gender.setConfidence(Float.valueOf(genderObj.optString("confidence")));
//		attribute.setGender(gender);
//		JSONObject raceObj = attributeObj.optJSONObject("race");
//		Face.Race race = new Face.Race();
//		race.setValue(raceObj.optString("value"));
//		race.setConfidence(Float.valueOf(raceObj.optString("confidence")));
//		attribute.setRace(race);
//		return attribute;
//	}
}
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import com.xiaoying.facedemo.MainApplication;
import com.xiaoying.facedemo.R;
import com.xiaoying.facedemo.group.adapter.GroupListAdapter;
import com.xiaoying.facedemo.utils.LogUtil;
import com.xiaoying.facedemo.widget.TitleBar;
import com.xiaoying.faceplusplus.api.config.RespConfig;
import com.xiaoying.faceplusplus.api.entity.Group;
import com.xiaoying.faceplusplus.api.entity.request.group.GroupDeleteReq;
import com.xiaoying.faceplusplus.api.entity.response.group.GroupDeleteResp;
import com.xiaoying.faceplusplus.api.entity.response.info.InfoGetGroupListResp;
import com.xiaoying.faceplusplus.api.service.GroupService;
import com.xiaoying.faceplusplus.api.service.InfoService;
/*
 * 文件名：GroupListActivity.java
 * 版权：<版权>
 * 描述：<描述>
 * 创建人：xiaoying
 * 创建时间：2013-5-20
 * 修改人：xiaoying
 * 修改时间：2013-5-20
 * 版本：v1.0
 */
package com.xiaoying.facedemo.group;





/**
 * 功能：Group列表
 * @author xiaoying
 */
public class GroupListActivity extends Activity {
	
	
	public static final int MODE_VIEW = 1;
	
	public static final int MODE_PICK = 2;
	
	public static final int MODE_CHOOSE = 3;
	
	public static final String EXTRA_MODE = "mode";

	public static final String EXTRA_GROUP = "group";
	
	public static final String EXTRA_GROUP_ARRAY = "person_array";
	
	public static final String EXTRA_POSITION = "position";
	
	public static final int REQUEST_CREATE_GROUP = 1000;
	
	public static final int REQUEST_MODIFY_GROUP = 1001;
	
	private String tag = GroupListActivity.class.getSimpleName();
	
	private TitleBar mTitleBar = null;
	
	private ListView mListView = null;
	
	private GroupListAdapter mAdapter = null;

	private ProgressDialog mProgressDialog = null;
	
	private int mMode = MODE_VIEW;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_group_list);
		
		mMode = getIntent().getIntExtra(EXTRA_MODE, MODE_VIEW);
		
		initView();
		
		new GetGroups().execute();
	}
	
	private void initView() {
		mTitleBar = (TitleBar) findViewById(R.id.tb_group_list_title);
		mListView = (ListView) findViewById(R.id.lv_group_list);
		mTitleBar.setLeftButton(R.string.backe, mLeftClick);
		
		mTitleBar.setLeftButton(R.string.backe, new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
			}
		});
		if(mMode == MODE_VIEW) {
			mTitleBar.setTitle(R.string.group_manager);
			mTitleBar.setRightButton(R.string.create, new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					gotoCreateGroup();
				}
			});
			mAdapter = new GroupListAdapter(this);
			mListView.setOnItemClickListener(mViewItemClick);
			mListView.setOnItemLongClickListener(mItemLongClick);
		} else if(mMode == MODE_PICK) {
			mTitleBar.setTitle(R.string.choose_group);
			mTitleBar.setRightButtonVisible(false);
			mAdapter = new GroupListAdapter(this, MODE_PICK);
			mListView.setOnItemClickListener(mPicItemClick);
		} else if(mMode == MODE_CHOOSE) {
			mTitleBar.setTitle(R.string.choose_group);
			mTitleBar.setRightButton(R.string.ok, new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					LogUtil.e(tag, mAdapter.getCheckedItems());
					Intent data = new Intent();
					data.putExtra(EXTRA_GROUP_ARRAY, (Serializable) mAdapter.getCheckedItems());
					setResult(RESULT_OK, data);
					finish();
				}
			});
			mAdapter = new GroupListAdapter(this, MODE_CHOOSE);
			mListView.setOnItemClickListener(mChooseItemClick);
		}
		
		mListView.setAdapter(mAdapter);
		
		initProgressDialog();
	}
	
	private void gotoCreateGroup() {
		Intent intent = new Intent(this, CreateGroupActivity.class);
		intent.putExtra(CreateGroupActivity.EXTRA_MODE, CreateGroupActivity.MODE_CREATE);
		startActivityForResult(intent, REQUEST_CREATE_GROUP);
	}
	
	private void gotoModifyGroup(Group group, int position) {
		Intent intent = new Intent(this, CreateGroupActivity.class);
		intent.putExtra(CreateGroupActivity.EXTRA_OLD_GROUP, group);
		intent.putExtra(CreateGroupActivity.EXTRA_MODE, CreateGroupActivity.MODE_MODIFY);
		intent.putExtra(EXTRA_POSITION, position);
		startActivityForResult(intent, REQUEST_MODIFY_GROUP);
	}
	
	private void initProgressDialog() {
		mProgressDialog = new ProgressDialog(this);
		mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		mProgressDialog.setCancelable(true);
	}
	
	private void showProgressDialog(CharSequence message) {
		if(mProgressDialog == null) {
			initProgressDialog();
		}
		mProgressDialog.setMessage(message);
		mProgressDialog.show();
	}
	
	private void dismissProgressDialog() {
		if(mProgressDialog != null && mProgressDialog.isShowing()) {
			mProgressDialog.dismiss();
		}
	}
	
	private View.OnClickListener mLeftClick = new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			switch (mMode) {
				case MODE_PICK:
				case MODE_CHOOSE:
					setResult(RESULT_CANCELED);
				default :
					break;
			}
			finish();
		}
	};
	
	/** MODE_VIEW下Item单击事件 */
	private AdapterView.OnItemClickListener mViewItemClick = new AdapterView.OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			
		}
	};
	
	/** MODE_PICK下Item单击事件 */
	private AdapterView.OnItemClickListener mPicItemClick = new AdapterView.OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			LogUtil.e(tag, mAdapter.getItem(position));
			Intent data = new Intent();
			data.putExtra(EXTRA_GROUP, mAdapter.getItem(position));
			if(getIntent().hasExtra(EXTRA_POSITION)) {
				data.putExtra(EXTRA_POSITION, getIntent().getIntExtra(EXTRA_POSITION, -1));
			}
			setResult(RESULT_OK, data);
			finish();
		}
	};
	
	/** MODE_CHOOSE下Item单击事件 */
	private AdapterView.OnItemClickListener mChooseItemClick = new AdapterView.OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			mAdapter.setChecked(position, !mAdapter.isChecked(position));
		}
	};
	
	/** Item长按事件(只在MODE_VIEW下) **/
	private AdapterView.OnItemLongClickListener mItemLongClick = new AdapterView.OnItemLongClickListener() {
		@Override
		public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
			AlertDialog.Builder builder = new AlertDialog.Builder(GroupListActivity.this)
			.setItems(R.array.group_list_long_click_menu, new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					switch (which) {
					case 0:
						break;
					case 1:
						gotoModifyGroup(mAdapter.getItem(position), position);
						break;
					case 2:
						new DeleteGroup(position).execute(mAdapter.getItem(position));
						break;
					default:
						break;
					}
				}
			});
			builder.create().show();
			return false;
		}
	};
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if(resultCode == RESULT_OK) {
			if(requestCode == REQUEST_CREATE_GROUP) {
				if(data != null) {
					mAdapter.add((Group) data.getSerializableExtra(CreateGroupActivity.EXTRA_NEW_GROUP));
				}
			} else if(requestCode == REQUEST_MODIFY_GROUP) {
				if(data != null) {
					int position = data.getIntExtra(EXTRA_POSITION, -1);
					if(position < 0) {
						Toast.makeText(GroupListActivity.this, R.string.sys_err, Toast.LENGTH_SHORT).show();
						return;
					}
					mAdapter.replace(position, (Group) data.getSerializableExtra(CreateGroupActivity.EXTRA_NEW_GROUP));
				}
			}
			
		}
	};
	
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_BACK) {
			finish();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}
	
	private class GetGroups extends AsyncTask<Void, Void, InfoGetGroupListResp> {