public class ContactDAO {

	private Context context;

	public ContactDAO() {
	}

	public ContactDAO(Context context) {
		this.context = context;
	}

	/**
	 * Ìí¼ÓÁªÏµÈË
	 * 
	 * @param contact
	 *            ÁªÏµÈËÊµÌå¶ÔÏó
	 * @param groupId
	 *            ×éºÅ
	 */
	public boolean addContact1(SortEntry contact, int groupId) {
		if (TextUtils.isEmpty(contact.mName)) {
			Toast.makeText(context, "ÐÕÃû²»ÄÜÎª¿Õ", Toast.LENGTH_LONG).show();
			return false;
		}
		ContentValues values = new ContentValues();
		Uri rawContactUri = context.getContentResolver().insert(
				RawContacts.CONTENT_URI, values);
		int rawContactId = (int) ContentUris.parseId(rawContactUri);
		// Ïòdata±í²åÈëÐÕÃû
		if (contact.mName != "") {
			values.clear();
			values.put(Data.RAW_CONTACT_ID, rawContactId);
			values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
			values.put(StructuredName.GIVEN_NAME, contact.mName);
			context.getContentResolver().insert(
					ContactsContract.Data.CONTENT_URI,values);
		}

		// ÏòdataÖÐ²åÈëµç»°ºÅÂë
		if (contact.mNum != "") {
			values.clear();
			String[] numbers = Tools.getPhoneNumber(contact.mNum);
			for (int i = 0; i < numbers.length; i++) {
				values.put(Data.RAW_CONTACT_ID, rawContactId);
				values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
				values.put(Phone.NUMBER, numbers[i]);
				values.put(Phone.TYPE, Phone.TYPE_MOBILE);
				context.getContentResolver().insert(
						ContactsContract.Data.CONTENT_URI, values);
			}
		}

		// Ìí¼ÓÍ·Ïñ
		if (contact.contactPhoto != null) {
			values.clear();
			values.put(Data.RAW_CONTACT_ID, rawContactId);
			values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
			values.put(Photo.PHOTO,
					ImageConvert.bitmapToByte(contact.contactPhoto));
			context.getContentResolver().insert(
					ContactsContract.Data.CONTENT_URI, values);
		}
		// // Ìí¼ÓµØÖ·
		// if (contact.getAddress() != "") {
		// values.clear();
		// values.put(Data.RAW_CONTACT_ID, rawContactId);
		// values.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
		// values.put(SipAddress.CONTENT_ITEM_TYPE, contact.getAddress());
		// context.getContentResolver().insert(
		// ContactsContract.Data.CONTENT_URI, values);
		// }
		// // Ìí¼ÓÓÊÏä
		// if (contact.getEmail() != "") {
		// values.clear();
		// values.put(Data.RAW_CONTACT_ID, rawContactId);
		// values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
		// values.put(Email.CONTENT_ITEM_TYPE, contact.getEmail());
		// context.getContentResolver().insert(
		// ContactsContract.Data.CONTENT_URI, values);
		// }
		if (groupId != 0) {
			new GroupDAO(context).addMemberToGroup(rawContactId, groupId);
		}
		return true;
	}

	/**
	 * É¾³ýÁªÏµÈË
	 * 
	 * @param rawContactId
	 *            ÁªÏµÈËid
	 */
	public void deleteContact(int rawContactId) {
		context.getContentResolver().delete(
				ContentUris.withAppendedId(RawContacts.CONTENT_URI,
						rawContactId), null, null);
	}

	/**
	 * ¸üÐÂÁªÏµÈË
	 * 
	 * @param rawContactId
	 *            ÁªÏµÈËid
	 */
	public void updataCotact(long rawContactId, SortEntry contact,
			int old_groupID) {
		ContentValues values = new ContentValues();
		// ¸üÐÂÐÕÃû
		values.put(StructuredName.GIVEN_NAME, contact.mName);
		context.getContentResolver().update(
				ContactsContract.Data.CONTENT_URI,
				values,
				Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + "=?",
				new String[] { String.valueOf(rawContactId),
						StructuredName.CONTENT_ITEM_TYPE });

		// ¸üÐÂµç»°
		if (contact.mNum != "") {
			values.clear();
			String[] numbers = Tools.getPhoneNumber(contact.mNum);
			for (int i = 0; i < numbers.length; i++) {
				values.put(Data.RAW_CONTACT_ID, rawContactId);
				values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
				values.put(Phone.NUMBER, numbers[i]);
				values.put(Phone.TYPE, Phone.TYPE_MOBILE);
//				context.getContentResolver().insert(
//						ContactsContract.Data.CONTENT_URI, values);
				context.getContentResolver().update(ContactsContract.Data.CONTENT_URI,
						values,
						Data.RAW_CONTACT_ID+"=? and "+Data.MIMETYPE+"=?",
						new String[]{String.valueOf(rawContactId),Phone.CONTENT_ITEM_TYPE});
			}
		}
		// ¸üÐÂÍ·Ïñ
		values.clear();
		if (contact.contactPhoto != null) {
			values.put(ContactsContract.CommonDataKinds.Photo.PHOTO,
					ImageConvert.bitmapToByte(contact.contactPhoto));
			context.getContentResolver().update(
					ContactsContract.Data.CONTENT_URI,
					values,
					Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + " =?",
					new String[] { String.valueOf(rawContactId),
							Photo.CONTENT_ITEM_TYPE });
		}
		// ¸üÐÂÈº×é
		if (contact.groupId != 0) {
			values.clear();
			values.put(
					ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID,
					contact.groupId);
			context.getContentResolver().update(
					ContactsContract.Data.CONTENT_URI,
					values,
					Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + " =?",
					new String[] { String.valueOf(rawContactId),
							GroupMembership.CONTENT_ITEM_TYPE });
		} else {
			new GroupDAO(context).deleteMemberFromGroup(
					Integer.parseInt(contact.mID), old_groupID);
		}
	}

	/**
	 * ¸üÐÂÁªÏµÈË ¿ªÊ¼Ã»ÓÐÍ·ÏñµÄÁªÏµÈË
	 * 
	 * @param rawContactId
	 *            ÁªÏµÈËid
	 */
	public void updataCotactNoPhoto(long rawContactId, SortEntry contact,
			int old_groupID) {
		ContentValues values = new ContentValues();
		// ¸üÐÂÐÕÃû
		values.put(StructuredName.GIVEN_NAME, contact.mName);
		context.getContentResolver().update(
				ContactsContract.Data.CONTENT_URI,
				values,
				Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + "=?",
				new String[] { String.valueOf(rawContactId),
						StructuredName.CONTENT_ITEM_TYPE });

		// ¸üÐÂµç»°
		if (contact.mNum != "") {
			values.clear();
			String[] numbers = Tools.getPhoneNumber(contact.mNum);
			for (int i = 0; i < numbers.length; i++) {
				values.put(Data.RAW_CONTACT_ID, rawContactId);
				values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
				values.put(Phone.NUMBER, numbers[i]);
				values.put(Phone.TYPE, Phone.TYPE_MOBILE);
				context.getContentResolver().update(ContactsContract.Data.CONTENT_URI,
						values,
						Data.RAW_CONTACT_ID+"=? and "+Data.MIMETYPE+"=?",
						new String[]{String.valueOf(rawContactId),Phone.CONTENT_ITEM_TYPE});
			}
		}
		// Ìí¼ÓÍ·Ïñ
		if (contact.contactPhoto != null) {
			values.clear();
			values.put(Data.RAW_CONTACT_ID, rawContactId);
			values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
			values.put(Photo.PHOTO,
					ImageConvert.bitmapToByte(contact.contactPhoto));
			context.getContentResolver().insert(
					ContactsContract.Data.CONTENT_URI, values);
		}
		// ¸üÐÂÈº×é
		if (contact.groupId != 0) {
			values.clear();
			values.put(
					ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID,
					contact.groupId);
			context.getContentResolver().update(
					ContactsContract.Data.CONTENT_URI,
					values,
					Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + " =?",
					new String[] { String.valueOf(rawContactId),
							GroupMembership.CONTENT_ITEM_TYPE });
		} else {
			new GroupDAO(context).deleteMemberFromGroup(
					Integer.parseInt(contact.mID), old_groupID);
		}
	}

	/**
	 * ¸üÐÂÁªÏµÈË ¸üÐÂÇ°Ã»ÓÐÈº×éµÄÁªÏµÈË
	 * 
	 * @param rawContactId
	 *            ÁªÏµÈËid
	 */
	public void updataCotactNoGroup(long rawContactId, SortEntry contact) {
		ContentValues values = new ContentValues();
		// ¸üÐÂÐÕÃû
		values.put(StructuredName.GIVEN_NAME, contact.mName);
		context.getContentResolver().update(
				ContactsContract.Data.CONTENT_URI,
				values,
				Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + "=?",
				new String[] { String.valueOf(rawContactId),
						StructuredName.CONTENT_ITEM_TYPE });

		// ¸üÐÂµç»°
		if (contact.mNum != "") {
			values.clear();
			String[] numbers = Tools.getPhoneNumber(contact.mNum);
			for (int i = 0; i < numbers.length; i++) {
				values.put(Data.RAW_CONTACT_ID, rawContactId);
				values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
				values.put(Phone.NUMBER, numbers[i]);
				values.put(Phone.TYPE, Phone.TYPE_MOBILE);
				context.getContentResolver().update(ContactsContract.Data.CONTENT_URI,
						values,
						Data.RAW_CONTACT_ID+"=? and "+Data.MIMETYPE+"=?",
						new String[]{String.valueOf(rawContactId),Phone.CONTENT_ITEM_TYPE});
			}
		}
		// ¸üÐÂÍ·Ïñ
		if (contact.contactPhoto != null) {
			values.clear();
			values.put(ContactsContract.CommonDataKinds.Photo.PHOTO,
					ImageConvert.bitmapToByte(contact.contactPhoto));
			context.getContentResolver().update(
					ContactsContract.Data.CONTENT_URI,
					values,
					Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + " =?",
					new String[] { String.valueOf(rawContactId),
							Photo.CONTENT_ITEM_TYPE });
		}
		// Ìí¼Óµ½Èº×é
		if (contact.groupId != 0) {
			new GroupDAO(context).addMemberToGroup(
					Integer.parseInt(contact.mID), contact.groupId);
		}
	}

	/**
	 * ¸üÐÂÁªÏµÈË ¸üÐÂÇ°Ã»ÓÐÍ·Ïñ¡¢Èº×éµÄÁªÏµÈË
	 * 
	 * @param rawContactId
	 *            ÁªÏµÈËid
	 */
	public void updataCotactNoG_Photo(long rawContactId, SortEntry contact) {
		ContentValues values = new ContentValues();
		// ¸üÐÂÐÕÃû
		values.put(StructuredName.GIVEN_NAME, contact.mName);
		context.getContentResolver().update(
				ContactsContract.Data.CONTENT_URI,
				values,
				Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + "=?",
				new String[] { String.valueOf(rawContactId),
						StructuredName.CONTENT_ITEM_TYPE });

		// ¸üÐÂµç»°
		if (contact.mNum != "") {
			values.clear();
			String[] numbers = Tools.getPhoneNumber(contact.mNum);
			for (int i = 0; i < numbers.length; i++) {
				values.put(Data.RAW_CONTACT_ID, rawContactId);
				values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
				values.put(Phone.NUMBER, numbers[i]);
				values.put(Phone.TYPE, Phone.TYPE_MOBILE);
				context.getContentResolver().update(ContactsContract.Data.CONTENT_URI,
						values,
						Data.RAW_CONTACT_ID+"=? and "+Data.MIMETYPE+"=?",
						new String[]{String.valueOf(rawContactId),Phone.CONTENT_ITEM_TYPE});
			}
		}
		// Ìí¼ÓÍ·Ïñ
		if (contact.contactPhoto != null) {
			values.clear();
			values.put(Data.RAW_CONTACT_ID, rawContactId);
			values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
			values.put(Photo.PHOTO,
					ImageConvert.bitmapToByte(contact.contactPhoto));
			context.getContentResolver().insert(
					ContactsContract.Data.CONTENT_URI, values);
		}
		// Ìí¼Óµ½Èº×é
		if (contact.groupId != 0) {
			new GroupDAO(context).addMemberToGroup(
					Integer.parseInt(contact.mID), contact.groupId);
		}
	}

	/**
	 * ¸üÐÂÁªÏµÈËËùÔÚ·Ö×é
	 * 
	 * @param groupID
	 *            µ±Ç°ÁªÏµÈËËùÔÚÈº×é
	 * @param contactID
	 *            ÁªÏµÈËID
	 */
	public void updateContactFromGroup(int groupID, String contactID) {
		ContentValues values = new ContentValues();
		// ¸üÐÂÈº×é
		values.clear();
		values.put(
				ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID,
				groupID);
		context.getContentResolver().update(ContactsContract.Data.CONTENT_URI,
				values,
				Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE + " =?",
				new String[] { contactID, GroupMembership.CONTENT_ITEM_TYPE });
	}

	Map<Integer, SortEntry> contactIdMap;
	List<SortEntry> contacts;

	/**
	 * ·µ»ØËùÓÐÁªÏµÈË ÁªÏµÈËid¡¢ÁªÏµÈËÐÕÃû¡¢ÁªÏµÈËºÅÂë¡¢ÁªÏµÈËÍ·Ïñ È¥³ýÁËÖØ¸´µÄÁªÏµÈË
	 */
	@SuppressLint("UseSparseArrays")
	public List<SortEntry> getContacts() {
		Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // ÁªÏµÈËµÄUri
		String[] projection = { ContactsContract.CommonDataKinds.Phone._ID,
				ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Phone.DATA1,
				ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
				ContactsContract.CommonDataKinds.Phone.PHOTO_ID,
				ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY, }; // ²éÑ¯µÄÁÐ
		Cursor cursor = context.getContentResolver().query(uri, projection,
				null, null, "sort_key COLLATE LOCALIZED asc"); // °´ÕÕsort_keyÉýÐò²éÑ¯

		if (cursor != null && cursor.getCount() > 0) {
			contactIdMap = new HashMap<Integer, SortEntry>();

			contacts = new ArrayList<SortEntry>();
			cursor.moveToFirst();
			for (int i = 0; i < cursor.getCount(); i++) {
				cursor.moveToPosition(i);
				String name = cursor.getString(1);
				String number = cursor.getString(2);
				int contactId = cursor.getInt(3);
				int photoId = cursor.getInt(4);
				String lookUpKey = cursor.getString(5);
				if (contactIdMap.containsKey(contactId)) {

				} else {
					SortEntry entry = null;
					if (!contactIdMap.containsValue(name)) {
						entry = new SortEntry();
						entry.mName = name;
						entry.mNum = number;
						entry.mID = String.valueOf(contactId);
						entry.photoId = photoId;
						entry.lookUpKey = lookUpKey;

						int groupId = new ContactDAO(context)
								.getGroupIdByContactId(contactId);
						entry.groupId = groupId;
						contacts.add(entry);
					}
					contactIdMap.put(contactId, entry);
				}
			}
			cursor.close();
		}
		return contacts;
	}

	/**
	 * »ñÈ¡Ä³¸ö·Ö×éÏÂÁªÏµÈËÐÅÏ¢
	 * 
	 * @param personId
	 * @param context
	 * @return ¸Ã·Ö×éÏÂµÄËùÓÐÁªÏµÈË
	 */
	public ArrayList<SortEntry> getContactsByGroupId(int groupId) {
		Uri uri = ContactsContract.Data.CONTENT_URI;

		String[] RAW_PROJECTION = new String[] { ContactsContract.Data.RAW_CONTACT_ID, };
		String RAW_CONTACTS_WHERE = ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID
				+ " =? and "
				+ ContactsContract.Data.MIMETYPE
				+ " = '"
				+ ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE
				+ "'";
		Cursor cursor = context.getContentResolver().query(uri, RAW_PROJECTION,
				RAW_CONTACTS_WHERE, new String[] { groupId + "" }, "data1 asc");

		ArrayList<SortEntry> list = new ArrayList<SortEntry>();
		while (cursor.moveToNext()) {
			// RAW_CONTACTS_ID
			int raw_contact_id = cursor.getInt(cursor
					.getColumnIndex("raw_contact_id"));

			SortEntry entry = new SortEntry();
			entry.mID = String.valueOf(raw_contact_id);
			entry = getContactByID(raw_contact_id, entry);
			list.add(entry);
			entry = null;
		}
		cursor.close();
		return list;
	}

	/**
	 * ¸ù¾ÝÁªÏµÈËID²éÕÒ¾ßÌåÐÅÏ¢
	 * 
	 * @param contactID
	 *            ÁªÏµÈËID
	 */
	public SortEntry getContactByID(int contactID, SortEntry entry) {
		Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // ÁªÏµÈËµÄUri

		String[] projection = { ContactsContract.CommonDataKinds.Phone._ID,
				ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Phone.DATA1,
				ContactsContract.CommonDataKinds.Phone.PHOTO_ID,
				ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY, }; // ²éÑ¯µÄÁÐ

		Cursor cursor = context.getContentResolver().query(uri, projection,
				Phone.RAW_CONTACT_ID + "=?", new String[] { contactID + "" },
				"data1 asc");
		cursor.moveToFirst();
		for (int i = 0; i < cursor.getCount(); i++) {
			cursor.moveToPosition(i);
			String name = cursor.getString(1);
			String number = cursor.getString(2);
			int photoId = cursor.getInt(3);
			String lookUpKey = cursor.getString(4);

			entry.mName = name;
			entry.mNum = number;
			entry.photoId = (int) photoId;
			entry.lookUpKey = lookUpKey;

		}
		cursor.close();
		return entry;
	}

	/**
	 * ¸ù¾ÝÁªÏµÈËID»ñÈ¡ÁªÏµÈËËùÔÚÈº×é
	 * 
	 * @param contactId
	 *            ÁªÏµÈËID
	 * @return
	 */
	public int getGroupIdByContactId(int contactId) {
		Uri uri = ContactsContract.Data.CONTENT_URI;

		String[] RAW_PROJECTION = new String[] { Data.MIMETYPE, Data.DATA1 };
		Cursor cursor = context.getContentResolver().query(uri, RAW_PROJECTION,
				Data.RAW_CONTACT_ID + "=?", new String[] { contactId + "" },
				null);
		int groupId = 0;
		while (cursor.moveToNext()) {
			String mime = cursor.getString(cursor.getColumnIndex("mimetype"));

			if ("vnd.android.cursor.item/group_membership".equals(mime)) {
				groupId = cursor.getInt(cursor.getColumnIndex("data1"));
			}
		}
		cursor.close();
		return groupId;
	}

	/**
	 * »ñÈ¡vCardÎÄ¼þÖÐµÄÁªÏµÈËÐÅÏ¢
	 * 
	 * @return
	 */
	public List<SortEntry> restoreContacts() throws Exception {
		List<SortEntry> contactInfoList = new ArrayList<SortEntry>();

		VCardParser parse = new VCardParser();
		VDataBuilder builder = new VDataBuilder();
		String file = Environment.getExternalStorageDirectory()
				+ "/example.vcf";

		BufferedReader reader = new BufferedReader(new InputStreamReader(
				new FileInputStream(file), "UTF-8"));

		String vcardString = "";
		String line;
		while ((line = reader.readLine()) != null) {
			vcardString += line + "\n";
		}
		reader.close();

		boolean parsed = parse.parse(vcardString, "UTF-8", builder);

		if (!parsed) {
			throw new VCardException("Could not parse vCard file: " + file);
		}

		List<VNode> pimContacts = builder.vNodeList;
		for (VNode contact : pimContacts) {
			SortEntry entry = new SortEntry();
			ContactStruct contactStruct = ContactStruct
					.constructContactFromVNode(contact, 1);
			// »ñÈ¡±¸·ÝÎÄ¼þÖÐµÄÁªÏµÈËµç»°ÐÅÏ¢
			List<PhoneData> phoneDataList = contactStruct.phoneList;
			// String[] numbers = new String[phoneDataList.size()];
			String numbers = "";
			for (int i = 0; i < phoneDataList.size(); i++) {
				// numbers[i] = phoneDataList.get(i).data;
				numbers += phoneDataList.get(i).data + "#";
			}
			entry.mNum = numbers;
			entry.mName = contactStruct.name;
			contactInfoList.add(entry);
		}

		return contactInfoList;
	}

	/**
	 * ·µ»ØËùÓÐÁªÏµÈË ÁªÏµÈËid¡¢ÁªÏµÈËÐÕÃû¡¢ÁªÏµÈËºÅÂë¡¢ÁªÏµÈËÍ·Ïñ È¥³ýÁËÖØ¸´µÄÁªÏµÈË
	 */
	@SuppressLint("UseSparseArrays")
	public List<SortEntry> getContacts1() {
		Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; // ÁªÏµÈËµÄUri
		String[] projection = { ContactsContract.CommonDataKinds.Phone._ID,
				ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
				ContactsContract.CommonDataKinds.Phone.DATA1,
				ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
				ContactsContract.CommonDataKinds.Phone.PHOTO_ID,
				ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY, }; // ²éÑ¯µÄÁÐ
		Cursor cursor = context.getContentResolver().query(uri, projection,
				null, null, "sort_key COLLATE LOCALIZED asc"); // °´ÕÕsort_keyÉýÐò²éÑ¯
	
		if (cursor != null && cursor.getCount() > 0) {
			contactIdMap = new HashMap<Integer, SortEntry>();
	
			contacts = new ArrayList<SortEntry>();
			cursor.moveToFirst();
			for (int i = 0; i < cursor.getCount(); i++) {
				cursor.moveToPosition(i);
				String name = cursor.getString(1);
				String number = cursor.getString(2);
				int contactId = cursor.getInt(3);
				int photoId = cursor.getInt(4);
				String lookUpKey = cursor.getString(5);
				if (contactIdMap.containsKey(contactId)) {
	
				} else {
					SortEntry entry = null;
					if (!contactIdMap.containsValue(name)) {
						entry = new SortEntry();
						entry.mName = name;
						entry.mNum = number;
						entry.mPY = PinyinUtils.getPingYin1(entry.mName);
						entry.mID = String.valueOf(contactId);
						entry.photoId = photoId;
						entry.lookUpKey = lookUpKey;
	
						contacts.add(entry);
					}
					contactIdMap.put(contactId, entry);
				}
			}
			cursor.close();
		}
		return contacts;
	}
} public class GroupDAO {

	private Context context;

	public GroupDAO(Context context) {
		this.context = context;
	}

	/**
	 * »ñÈ¡ËùÓÐÁªÏµÈË·Ö×é
	 * 
	 * @param context
	 *            ÉÏÏÂÎÄ
	 * @return
	 */
	public ArrayList<GroupBean> getGroups() {
		Cursor cursor = context.getContentResolver().query(Groups.CONTENT_URI,
				null, null, null, null);
		ArrayList<GroupBean> list = new ArrayList<GroupBean>();

		while (cursor.moveToNext()) {
			// µÃµ½×´Ì¬--ÊÇ·ñ±»É¾³ý
			int isDeleted = cursor
					.getInt(cursor.getColumnIndex(Groups.DELETED));
			if (isDeleted == 0) {
				GroupBean gb = new GroupBean();
				// Ìí¼Ó×éÃû
				String name = cursor.getString(cursor
						.getColumnIndex(Groups.TITLE));
				gb.setName(name);
				// Ìí¼Ó×éid
				int groupId = cursor.getInt(cursor.getColumnIndex(Groups._ID));
				gb.setId(groupId);
				int count = new ContactDAO(context).getContactsByGroupId(
						groupId).size();
				gb.setCount(count);
				list.add(gb);
			}
		}
		cursor.close();
		return list;
	}

	/**
	 * ÐÂ½¨×é
	 * 
	 * @param groupName
	 *            ×éÃû
	 * @param context
	 *            ÉÏÏÂÎÄ
	 */
	public void addGroup(String groupName) {
		ContentValues values = new ContentValues();
		values.put(Groups.TITLE, groupName);
		context.getContentResolver().insert(Groups.CONTENT_URI, values);
	}

	/**
	 * É¾³ý×é
	 * 
	 * @param groupId
	 *            ×éid
	 * @param context
	 *            ÉÏÏÂÎÄ
	 */
	public void deleteGroup(int groupId) {
		context.getContentResolver().delete(
				Uri.parse(Groups.CONTENT_URI + "?"
						+ ContactsContract.CALLER_IS_SYNCADAPTER + "=true"),
				Groups._ID + "=" + groupId, null);
	}

	/**
	 * Ìí¼Ó³ÉÔ±
	 * 
	 * @param groupId
	 *            ÁªÏµÈËid
	 * @param groupId
	 *            ×éºÅ
	 * @param context
	 *            ÉÏÏÂÎÄ
	 */
	public void addMemberToGroup(int personId, int groupId) {
		ContentValues values = new ContentValues();
		values.put(
				ContactsContract.CommonDataKinds.GroupMembership.RAW_CONTACT_ID,
				personId);

		values.put(
				ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID,
				groupId);

		values.put(
				ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE,
				ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);

		context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
				values);
	}

	/**
	 * ´Ó×éÖÐÉ¾³ý³ÉÔ±
	 * 
	 * @param personId
	 *            ³ÉÔ±id
	 * @param groupId
	 *            ×éºÅ
	 * @param context
	 *            ÉÏÏÂÎÄ
	 */
	public void deleteMemberFromGroup(int personId, int groupId) {
		context
				.getContentResolver()
				.delete(ContactsContract.Data.CONTENT_URI,
						ContactsContract.CommonDataKinds.GroupMembership.RAW_CONTACT_ID
								+ "=? and "
								+ ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID
								+ "=? and "
								+ ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE
								+ "=?",
						new String[] {
								"" + personId,
								"" + groupId,
								ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE });
		// Delete a contact from a group
//		Uri uri = Data.CONTENT_URI;
//		Uri.Builder b = uri.buildUpon();
//		b.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true");
//		uri = b.build();
//
//		context.getContentResolver()
//				.delete(uri,
//						Data.RAW_CONTACT_ID
//								+ "="
//								+ personId
//								+ " AND "
//								+ ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID
//								+ " =" + groupId, null);
	}

	/**
	 * ÐÞ¸ÄÈº×éÃû
	 * 
	 * @param rawContactId
	 */
	public void updataGroup(int groupId, String groupName) {
		System.out.println("update group...");
		ContentValues values = new ContentValues();
		values.put(Groups.TITLE, groupName);
		String where = ContactsContract.Groups._ID + "=? ";
		String[] selectionArgs = new String[] { String.valueOf(groupId) };
		context.getContentResolver().update(Groups.CONTENT_URI, values, where,
				selectionArgs);
	}

	public String getGroupNameByGroupId(long groupId) {
		String groupName = "";
		String[] PROJECTION = new String[] { Groups.TITLE };
		String SELECTION = Groups._ID + "=?";
		Cursor cursor = context.getContentResolver().query(Groups.CONTENT_URI,
				PROJECTION, SELECTION, new String[] { groupId + "" }, null);
		while (cursor.moveToNext()) {
			groupName = cursor.getString(cursor.getColumnIndex(Groups.TITLE));
		}
		cursor.close();
		return groupName;
	}

	public int getIdByGroupName(String groupName) {
		int groupId = 0;
		String[] PROJECTION = new String[] { Groups._ID };
		String SELECTION = Groups.TITLE + "=?";
		Cursor cursor = context.getContentResolver().query(Groups.CONTENT_URI,
				PROJECTION, SELECTION, new String[] { groupName + "" }, null);
		while (cursor.moveToNext()) {
			groupId = cursor.getInt(cursor.getColumnIndex(Groups._ID));
		}
		cursor.close();
		return groupId;
	}
} @SuppressLint({ "ViewHolder", "InflateParams" })
public  class FilterAdapter extends BaseAdapter{
	
	private LayoutInflater mInflater;
	private ArrayList<SortEntry> data;
	private Context context;
	
    public FilterAdapter(Context context,
    		ArrayList<SortEntry> data) {
	    this.mInflater = LayoutInflater.from(context);
	    this.data = data;
	    this.context = context;
    }

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

	@Override
	public Object getItem(int arg0) {
		return data.get(arg0);
	}

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

	@Override
	public View getView(int arg0, View arg1, ViewGroup arg2) {
		arg1 = mInflater.inflate(R.layout.list_item_home_contacts, null);
		
		//ÐÕÃûÏÔÊ¾
		TextView nameCtrl = (TextView)arg1.findViewById(R.id.contacts_name);			
		String strName = data.get(arg0).mName;
		nameCtrl.setText(strName);
		
		//Í·Ïñ
		ImageView photo = (ImageView) arg1.findViewById(R.id.contact_photo);
		int photoId = data.get(arg0).photoId;
		String contactID = data.get(arg0).mID;
		if(0 == photoId){
			photo.setImageResource(R.drawable.default_contact_photo);
		}else{
        	Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,Integer.parseInt(contactID));
			InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri); 
			Bitmap contactPhoto = BitmapFactory.decodeStream(input);
			photo.setImageBitmap(contactPhoto);
        }
		//ÊÇ·ñÑ¡Ôñ
        ImageView chooseView = (ImageView)arg1.findViewById(R.id.choose_contact);
        chooseView.setVisibility(View.GONE);
		
		return arg1;
	}
} public class GroupAdapter extends BaseAdapter {

	private Context context ;
	private List<GroupBean> groupList;
	public GroupAdapter(Context context,List<GroupBean> groupList){
		this.context = context;
		this.groupList = groupList;
	}
	public int getCount() {
		return groupList.size();
	}

	public Object getItem(int position) {
		return groupList.get(position);
	}

	public long getItemId(int position) {
		return 0;
	}
	@SuppressLint("ViewHolder") public View getView(int position, View convertView, ViewGroup parent) {
		GroupBean gb = groupList.get(position);
		View view = View.inflate(context,R.layout.list_item_popview,null);
		TextView button = (TextView) view.findViewById(R.id.btn_group_list);
		button.setText(gb.getName());
		return view;
	}

} public class GroupBean implements Parcelable{

	private int id;
	private String name;
	private int count;
	
	public GroupBean() {
		super();
	}
	public GroupBean(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	public GroupBean(int id, String name, int count) {
		super();
		this.id = id;
		this.name = name;
		this.count = count;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	/**
	 * ÐòÁÐ»¯
	 */
	@Override
	public int describeContents() {
		return 0;
	}
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeInt(getId());
		dest.writeString(getName());
		dest.writeInt(getCount());
	}
	//ÖØÐ´Creator
	 public static final Parcelable.Creator<GroupBean> CREATOR = new Creator<GroupBean>(){

		@Override
		public GroupBean createFromParcel(Parcel source) {
			GroupBean group = new GroupBean();
			group.id = source.readInt();
			group.name = source.readString();
			group.count = source.readInt();
			return group;
		}

		@Override
		public GroupBean[] newArray(int size) {
			return new GroupBean[size];
		}
		 
	 };
} public class SortEntry implements Parcelable{
	public String mID; // ÔÚÊý¾Ý¿âÖÐµÄIDºÅ
	public String mName; // ÐÕÃû
	public String mPY; // ÐÕÃûÆ´Òô
	public String mNum; // µç»°ºÅÂë
	public String mFisrtSpell; // ÖÐÎÄÃûÊ××ÖÄ¸ Àý:ÕÅÑ©±ù:zxb
	public int mchoose; // ÊÇ·ñÑ¡ÖÐ 0--Î´Ñ¡ÖÐ 1---Ñ¡ÖÐ
	public int mOrder; // ÔÚÔ­CursorÖÐµÄÎ»ÖÃ
	public String lookUpKey;
	public int photoId;
	public int groupId;
	public String groupName;
	public Bitmap contactPhoto;// ÕÕÆ¬
	public String formattedNumber;
	@Override
	public int describeContents() {
		return 0;
	}
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeString(mID);
		dest.writeString(mName);
		dest.writeString(mPY);
		dest.writeString(mNum);
		dest.writeString(mFisrtSpell);
		dest.writeInt(mchoose);
		dest.writeInt(mOrder);
		dest.writeString(lookUpKey);
		dest.writeInt(photoId);
		dest.writeInt(groupId);
		dest.writeString(groupName);
		dest.writeString(formattedNumber);
	}
	

	// ÖØÐ´Creator
	public static final Parcelable.Creator<SortEntry> CREATOR = new Creator<SortEntry>() {

		@Override
		public SortEntry createFromParcel(Parcel source) {
			SortEntry contact = new SortEntry();
			contact.mID = source.readString();
			contact.mName = source.readString();
			contact.mPY = source.readString();
			contact.mNum = source.readString();
			contact.mFisrtSpell = source.readString();
			contact.mchoose = source.readInt();
			contact.mOrder = source.readInt();
			contact.lookUpKey = source.readString();
			contact.photoId = source.readInt();
			contact.groupId = source.readInt();
			contact.groupName = source.readString();
			contact.formattedNumber = source.readString();
			return contact;
		}

		@Override
		public SortEntry[] newArray(int size) {
			return new SortEntry[size];
		}

	};
} @SuppressLint("ClickableViewAccessibility")
public class ClearEditText extends EditText implements  
        OnFocusChangeListener, TextWatcher { 
	/**
	 * É¾³ý°´Å¥µÄÒýÓÃ
	 */
    private Drawable mClearDrawable; 
 
    public ClearEditText(Context context) { 
    	this(context, null); 
    } 
 
    public ClearEditText(Context context, AttributeSet attrs) { 
    	//ÕâÀï¹¹Ôì·½·¨Ò²ºÜÖØÒª£¬²»¼ÓÕâ¸öºÜ¶àÊôÐÔ²»ÄÜÔÙXMLÀïÃæ¶¨Òå
    	this(context, attrs, android.R.attr.editTextStyle); 
    } 
    
    public ClearEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }
    
    
    private void init() { 
    	//»ñÈ¡EditTextµÄDrawableRight,¼ÙÈçÃ»ÓÐÉèÖÃÎÒÃÇ¾ÍÊ¹ÓÃÄ¬ÈÏµÄÍ¼Æ¬
    	mClearDrawable = getCompoundDrawables()[2]; 
        if (mClearDrawable == null) { 
        	mClearDrawable = getResources() 
                    .getDrawable(R.drawable.emotionstore_progresscancelbtn); 
        } 
        mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight()); 
        setClearIconVisible(false); 
        setOnFocusChangeListener(this); 
        addTextChangedListener(this); 
    } 
 
 
    /**
     * ÒòÎªÎÒÃÇ²»ÄÜÖ±½Ó¸øEditTextÉèÖÃµã»÷ÊÂ¼þ£¬ËùÒÔÎÒÃÇÓÃ¼Ç×¡ÎÒÃÇ°´ÏÂµÄÎ»ÖÃÀ´Ä£Äâµã»÷ÊÂ¼þ
     * µ±ÎÒÃÇ°´ÏÂµÄÎ»ÖÃ ÔÚ  EditTextµÄ¿í¶È - Í¼±êµ½¿Ø¼þÓÒ±ßµÄ¼ä¾à - Í¼±êµÄ¿í¶È  ºÍ
     * EditTextµÄ¿í¶È - Í¼±êµ½¿Ø¼þÓÒ±ßµÄ¼ä¾àÖ®¼äÎÒÃÇ¾ÍËãµã»÷ÁËÍ¼±ê£¬ÊúÖ±·½ÏòÃ»ÓÐ¿¼ÂÇ
     */
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
        if (getCompoundDrawables()[2] != null) { 
            if (event.getAction() == MotionEvent.ACTION_UP) { 
            	boolean touchable = event.getX() > (getWidth() 
                        - getPaddingRight() - mClearDrawable.getIntrinsicWidth()) 
                        && (event.getX() < ((getWidth() - getPaddingRight())));
                if (touchable) { 
                    this.setText(""); 
                } 
            } 
        } 
 
        return super.onTouchEvent(event); 
    } 
 
    /**
     * µ±ClearEditText½¹µã·¢Éú±ä»¯µÄÊ±ºò£¬ÅÐ¶ÏÀïÃæ×Ö·û´®³¤¶ÈÉèÖÃÇå³ýÍ¼±êµÄÏÔÊ¾ÓëÒþ²Ø
     */
    @Override 
    public void onFocusChange(View v, boolean hasFocus) { 
        if (hasFocus) { 
            setClearIconVisible(getText().length() > 0); 
        } else { 
            setClearIconVisible(false); 
        } 
    } 
 
 
    /**
     * ÉèÖÃÇå³ýÍ¼±êµÄÏÔÊ¾ÓëÒþ²Ø£¬µ÷ÓÃsetCompoundDrawablesÎªEditText»æÖÆÉÏÈ¥
     * @param visible
     */
    protected void setClearIconVisible(boolean visible) { 
        Drawable right = visible ? mClearDrawable : null; 
        setCompoundDrawables(getCompoundDrawables()[0], 
                getCompoundDrawables()[1], right, getCompoundDrawables()[3]); 
    } 
     
    
    /**
     * µ±ÊäÈë¿òÀïÃæÄÚÈÝ·¢Éú±ä»¯µÄÊ±ºò»Øµ÷µÄ·½·¨
     */
    @Override 
    public void onTextChanged(CharSequence s, int start, int count, 
            int after) { 
        setClearIconVisible(s.length() > 0); 
    } 
 
    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, 
            int after) { 
         
    } 
 
    @Override 
    public void afterTextChanged(Editable s) { 
         
    } 
    
   
    /**
     * ÉèÖÃ»Î¶¯¶¯»­
     */
    public void setShakeAnimation(){
    	this.setAnimation(shakeAnimation(5));
    }
    
    
    /**
     * »Î¶¯¶¯»­
     * @param counts 1ÃëÖÓ»Î¶¯¶àÉÙÏÂ
     * @return
     */
    public static Animation shakeAnimation(int counts){
    	Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
    	translateAnimation.setInterpolator(new CycleInterpolator(counts));
    	translateAnimation.setDuration(1000);
    	return translateAnimation;
    }
 
 
} public class ContactsCursorAdapter extends CursorAdapter{
	int ItemPos = -1;
	
	@SuppressWarnings("deprecation")
	public ContactsCursorAdapter(Context context, Cursor c) {
		super(context, c);
	}
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ItemPos = position;

		return super.getView(position,convertView,parent);
	}

	@SuppressLint("DefaultLocale")
	@Override
	public void bindView(View view, Context context, Cursor cursor) {
		if(cursor == null)
		{
			return;
		}
        TextView name = (TextView) view.findViewById(R.id.contacts_name);
        name.setText(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
	    
        ImageView photo = (ImageView) view.findViewById(R.id.contact_photo);
        
        int photoId = cursor.getInt
        		(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_ID));
        String contactID = cursor.getString(cursor
				.getColumnIndex(Data.RAW_CONTACT_ID));
        if(0 == photoId){
        	photo.setImageResource(R.drawable.default_contact_photo);
        }else{
        	Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,Integer.parseInt(contactID));
			InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri); 
			Bitmap contactPhoto = BitmapFactory.decodeStream(input);
			photo.setImageBitmap(contactPhoto);
        }
        
        ImageView chooseView = (ImageView)view.findViewById(R.id.choose_contact);
        chooseView.setVisibility(View.GONE);
        
		//×ÖÄ¸ÌáÊ¾textviewµÄÏÔÊ¾ 
		TextView letterTag = (TextView)view.findViewById(R.id.pb_item_LetterTag);
		//»ñµÃµ±Ç°ÐÕÃûµÄÆ´ÒôÊ××ÖÄ¸
		String firstLetter = PinyinUtils.getPingYin(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))).substring(0,1).toUpperCase();
		
		//Èç¹ûÊÇµÚ1¸öÁªÏµÈË ÄÇÃ´letterTagÊ¼ÖÕÒªÏÔÊ¾
		if(ItemPos == 0)
		{
			letterTag.setVisibility(View.VISIBLE);
			letterTag.setText(firstLetter);
		}			
		else
		{
			//»ñµÃÉÏÒ»¸öÐÕÃûµÄÆ´ÒôÊ××ÖÄ¸
			cursor.moveToPrevious();
			String firstLetterPre = PinyinUtils.getPingYin(cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))).substring(0,1).toUpperCase();
			//±È½ÏÒ»ÏÂÁ½ÕßÊÇ·ñÏàÍ¬
			if(firstLetter.equals(firstLetterPre))
			{
				letterTag.setVisibility(View.GONE);
			}
			else 
			{
				letterTag.setVisibility(View.VISIBLE);
				letterTag.setText(firstLetter);
			}
		}
		
	}
	@Override
	public View newView(Context context, Cursor cursor, ViewGroup parent) {
		return LayoutInflater.from(context).inflate(R.layout.list_item_home_contacts, parent,false);
	}
} @SuppressLint({ "DefaultLocale", "UseSparseArrays" })
public class SortCursor extends CursorWrapper {
	private ArrayList<SortEntry> mSortList;
	private ArrayList<SortEntry> mFilterList;// É¸Ñ¡ºóµÄÊý¾Ýlist
	private Cursor mCursor;
	private int mPos;
	private static Context m_context;
	private Map<String, SortEntry> contactIdMap;

	public static void init(Context context) {
		m_context = context;
	}

	public SortCursor(Cursor cursor) {
		super(cursor);
		System.out.println("SortCursor...");
		mCursor = cursor;
		mSortList = new ArrayList<SortEntry>();
		contactIdMap = new HashMap<String, SortEntry>();
		for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {

			String raw_contact_id = cursor.getString(cursor
					.getColumnIndex(Data.RAW_CONTACT_ID));
			String name = cursor
					.getString(cursor
							.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
			if (contactIdMap.containsKey(raw_contact_id)) {
			} else {
				SortEntry entry = null;
				if (!contactIdMap.containsValue(name)) {
					entry = new SortEntry();
					entry.mID = raw_contact_id;
					entry.mName = name;

					entry.mOrder = cursor.getPosition();
					entry.mPY = PinyinUtils.getPingYin1(entry.mName);
					String number = "";
					int phoneCount = cursor
							.getInt(cursor
									.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
					if (phoneCount > 0) {
						Cursor phoneCursor = m_context
								.getContentResolver()
								.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
										null,
										ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID
												+ "=" + raw_contact_id,null,
										null);
						while (phoneCursor.moveToNext()) {
							String phoneNumber = phoneCursor
									.getString(phoneCursor
											.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
							number += phoneNumber + "#";
						}
						phoneCursor.close();
					} else {
						number = cursor
								.getString(cursor
										.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
					}
					entry.mNum = number;
					entry.mFisrtSpell = PinyinUtils.getFirstSpell(entry.mName);
					entry.mchoose = 0;
					entry.lookUpKey = cursor
							.getString(cursor
									.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY));
					entry.photoId = cursor
							.getInt(cursor
									.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_ID));
					int groupId = new ContactDAO(m_context)
							.getGroupIdByContactId(Integer.parseInt(entry.mID));
					entry.groupId = groupId;
					mSortList.add(entry);
					System.out.println("id:"+raw_contact_id+"name:"+name+"number:"+number);
				}
				contactIdMap.put(entry.mID, entry);
			}
		}
		System.out.println("loaded...");
		Collections.sort(mSortList, new ComparatorPY());

	}

	private class ComparatorPY implements Comparator<SortEntry> {

		@Override
		public int compare(SortEntry lhs, SortEntry rhs) {
			String str1 = lhs.mPY;
			String str2 = rhs.mPY;
			return str1.compareToIgnoreCase(str2);
		}
	}

	@Override
	public boolean moveToPosition(int position) {
		mPos = position;
		if (position < mSortList.size() && position >= 0) {
			return mCursor.moveToPosition(mSortList.get(position).mOrder);
		}

		if (position < 0) {
			mPos = -1;
		}
		if (position >= mSortList.size()) {
			mPos = mSortList.size();
		}
		return mCursor.moveToPosition(position);
	}

	@Override
	public boolean moveToFirst() {
		return moveToPosition(0);
	}

	@Override
	public boolean moveToLast() {
		return moveToPosition(getCount() - 1);
	}

	@Override
	public boolean moveToNext() {
		return moveToPosition(mPos + 1);
	}

	@Override
	public boolean moveToPrevious() {
		return moveToPosition(mPos - 1);
	}

	public int binarySearch(String letter) {
		for (int index = 0; index < mSortList.size(); index++) {
			if (mSortList.get(index).mPY.substring(0, 1).compareToIgnoreCase(
					letter) == 0) {
				return index;
			}
		}
		return -1;
	}

	public ArrayList<SortEntry> GetContactsArray() {

		return mSortList;
	}

	/**
	 * »ñÈ¡ÒªÌí¼ÓµÄ³ÉÔ±
	 * 
	 * @param groupId
	 *            Ìí¼Óµ½ÄÇÒ»×é
	 * @return
	 */
	public ArrayList<SortEntry> getAddContactsArray(int groupId) {
		ArrayList<SortEntry> addContactsList = new ArrayList<>();
		for (SortEntry entry : mSortList) {
			if (entry.groupId == 0) {
				addContactsList.add(entry);
			}
		}
		return addContactsList;
	}

	/**
	 * »ñÈ¡ÒªÒÆ³ýµÄ³ÉÔ±
	 * 
	 * @param groupId
	 *            ´ÓÄ³Ò»×éÒÆ³ý³ÉÔ±
	 * @return
	 */
	public ArrayList<SortEntry> getRemoveContactsArray(int groupId) {
		ArrayList<SortEntry> removeContactsList = new ArrayList<>();
		for (SortEntry entry : mSortList) {
			if (entry.groupId == groupId) {
				removeContactsList.add(entry);
			}
		}
		return removeContactsList;
	}

	/**
	 * Ö÷½çÃæËÑË÷ÁªÏµÈË
	 * 
	 * @param keyword
	 * @return
	 */
	public ArrayList<SortEntry> filterSearch(String keyword) {
		mFilterList = new ArrayList<SortEntry>();
		mFilterList.clear();

		if (keyword.startsWith("0") || keyword.startsWith("1")) {
			for (SortEntry contact : mSortList) {
				if (contact.mNum != null && contact.mName != null) {
					if (contact.mNum.contains(keyword)
							|| contact.mName.contains(keyword)) {
						mFilterList.add(contact);
					}
				}
			}
			return mFilterList;
		}

		final String result = PinyinUtils.getPingYin1(keyword);
		for (SortEntry contact : mSortList) {
			if (contains(contact, result)) {
				mFilterList.add(contact);
			}
		}
		return mFilterList;
	}

	/**
	 * ·Ö×é¹ÜÀí--Ìí¼Ó/ÒÆ³ý³ÉÔ±--ËÑË÷ÁªÏµÈË
	 * 
	 * @param keyword
	 * @return
	 */
	public ArrayList<SortEntry> filterSearch1(String keyword,
			ArrayList<SortEntry> sortList) {
		mFilterList = new ArrayList<SortEntry>();
		mFilterList.clear();

		if (keyword.startsWith("0") || keyword.startsWith("1")) {
			for (SortEntry contact : sortList) {
				if (contact.mNum != null && contact.mName != null) {
					if (contact.mNum.contains(keyword)
							|| contact.mName.contains(keyword)) {
						mFilterList.add(contact);
					}
				}
			}
			return mFilterList;
		}

		final String result = PinyinUtils.getPingYin1(keyword);
		for (SortEntry contact : sortList) {
			if (contains(contact, result)) {
				mFilterList.add(contact);
			}
		}
		return mFilterList;
	}

	/**
	 * ¸ù¾ÝÆ´ÒôËÑË÷
	 * 
	 * @param str
	 *            ÕýÔò±í´ïÊ½
	 * @param pyName
	 *            Æ´Òô
	 * @param isIncludsive
	 *            ËÑË÷Ìõ¼þÊÇ·ñ´óÓÚ6¸ö×Ö·û
	 * @return
	 */
	public static boolean contains(SortEntry contact, String search) {
		if (TextUtils.isEmpty(contact.mName) || TextUtils.isEmpty(search)) {
			return false;
		}
		boolean flag = false;

		// ¼òÆ´Æ¥Åä£¬Èç¹ûÊäÈëÔÚ×Ö·û´®³¤¶È´óÓÚ6¾Í²»°´Ê××ÖÄ¸Æ¥Åä
		if (search.length() < 6) {
			String firstLetters = UnicodeGBK2Alpha
					.getSimpleCharsOfString(contact.mName);

			Pattern firstLetterMatcher = Pattern.compile("^" + search,
					Pattern.CASE_INSENSITIVE);
			flag = firstLetterMatcher.matcher(firstLetters).find();
		}

		if (!flag) {// È«Æ´
			Pattern pattern2 = Pattern
					.compile(search, Pattern.CASE_INSENSITIVE);
			Matcher matcher2 = pattern2.matcher(PinyinUtils
					.getPingYin1(contact.mName));
			flag = matcher2.find();
		}
		return flag;
	}

	public ArrayList<SortEntry> FilterSearch(String keyword) {
		mFilterList = new ArrayList<SortEntry>();
		mFilterList.clear();
		// ±éÀúmArrayList
		for (int i = 0; i < mSortList.size(); i++) {
			// Èç¹û±éÀúµ½List°üº¬ËùÊäÈë×Ö·û´®
			if (mSortList.get(i).mNum.indexOf(keyword) > 0
					|| isStrInString(mSortList.get(i).mPY, keyword)
					|| mSortList.get(i).mName.contains(keyword)
					|| isStrInString(mSortList.get(i).mFisrtSpell, keyword)) {
				// ½«±éÀúµ½µÄÔªËØÖØÐÂ×é³ÉÒ»¸ölist

				SortEntry entry = new SortEntry();
				entry.mName = mSortList.get(i).mName;
				entry.mID = mSortList.get(i).mID;
				entry.mOrder = i;
				entry.mPY = mSortList.get(i).mPY;
				entry.mNum = mSortList.get(i).mNum;
				mFilterList.add(entry);
			}
		}
		return mFilterList;
	}

	public boolean isStrInString(String bigStr, String smallStr) {
		if (bigStr.toUpperCase().indexOf(smallStr.toUpperCase()) > -1) {
			return true;
		} else {
			return false;
		}
	}

	public String getName(int index) {
		return mSortList.get(index).mName;

	}

	public String getNumber(int index) {
		return mSortList.get(index).mNum;

	}

	public String getID(int index) {
		return mSortList.get(index).mID;
	}

	public String getLookUpKey(int index) {
		return mSortList.get(index).lookUpKey;
	}

	public int getPhotoId(int index) {
		return mSortList.get(index).photoId;
	}

	// ¹ýÂËÈº×é
	public ArrayList<SortEntry> filterGroup(int groupId) {
		ArrayList<SortEntry> groupList = new ArrayList<SortEntry>();
		groupList.clear();
		for (SortEntry entry : mSortList) {
			if (entry.groupId == groupId) {
				groupList.add(entry);
			}
		}
		return groupList;
	}
} public class SortCursorLoader extends CursorLoader{

	public SortCursorLoader(Context context, Uri uri, String[] projection,
			String selection, String[] selectionArgs, String sortOrder) {
		super(context, uri, projection, selection, selectionArgs, sortOrder);
	}

	@Override
	public Cursor loadInBackground() {
		Cursor cursor = super.loadInBackground();
		return new SortCursor(cursor);
	}

} public class ContactsContentObserver extends ContentObserver{

	public ContactsContentObserver(Handler handler) {
		super(handler);
	}
	@Override
	public void onChange(boolean selfChange) {
		
		Log.i("datachanged", "ÁªÏµÈËÊý¾Ý¿â·¢ÉúÁË±ä»¯");
	}

} public class AddContactActivity extends Activity {

	private Button btn_contact_back;
	private TextView btn_contact_title;
	private Button btn_save_contact;

	public EditText et_name;
	private ImageButton btn_img;
	private Bitmap contactPhotos;
	public String photoUri;
	public EditText et_phone;
	public EditText et_email;
	public EditText et_address;
	private Spinner sp_group;

	private ProgressDialog m_dialogLoading;

	private List<GroupBean> groupList;
	private String groupName;
	private ContactDAO cat;

	// Ìí¼Ó°´Å¥
	private ImageButton add_phone_row_btn;

	public EditText et_phone_2;
	private ImageButton add_phone_row_btn_2;

	public EditText et_phone_3;
	private ImageButton add_phone_row_btn_3;

	/* Í·ÏñÃû³Æ */
	private static final String IMAGE_FILE_NAME = "faceImage.jpg";

	/* ÇëÇóÂë */
	private static final int IMAGE_REQUEST_CODE = 0;
	private static final int CAMERA_REQUEST_CODE = 1;
	private static final int RESULT_REQUEST_CODE = 2;
	// ÅÄÕÕ°´Å¥
//	private ImageButton imagebtn_camera;
	// ´ÓÍ¼¿âÑ¡ÔñÕÕÆ¬°´Å¥
//	private ImageButton imagebtn_glary;

	private SortEntry entry;
	private int flag = 0;
	private int loadlag = 0;
	private int groupFlag = 0;// ÁªÏµÈËÊÇ·ñÒÑ´æÔÚ·Ö×é 0--none 1--have
	private int photoFlag = 0;// ÁªÏµÈËÊÇ·ñÒÑ´æÔÚÍ·Ïñ

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);

		setContentView(R.layout.contact_addnew);
		findId();
		String type = getIntent().getStringExtra("type");
		if (type != null && type.equals(Parameter.CONTACT_EDIT_TYPE)) {
			entry = getIntent().getParcelableExtra(Parameter.CONTACT_EDIT_KEY);
			groupName = entry.groupName;
			flag = 1;
			if (entry.groupId != 0) {
				groupFlag = 1;
			}
			if (entry.photoId != 0) {
				photoFlag = 1;
			}
			btn_contact_title.setText(Parameter.EDIT_CONTACT_TITLE);

			et_name.setText(entry.mName);
			String[] numbers = Tools.getPhoneNumber(entry.mNum);
			if (numbers.length == 1) {
				et_phone.setText(numbers[0]);
			} else if (numbers.length == 2) {// 2¸öºÅÂë
				et_phone.setText(numbers[0]);
				et_phone_2 = (EditText) this.findViewById(R.id.et_phone_2);
				View v = (View) et_phone_2.getParent();
				v.setVisibility(View.VISIBLE);
				et_phone_2.setText(numbers[1]);
			} else if (numbers.length == 3) {// 3¸öºÅÂë
				et_phone.setText(numbers[0]);
				et_phone_2 = (EditText) this.findViewById(R.id.et_phone_2);
				View v = (View) et_phone_2.getParent();
				v.setVisibility(View.VISIBLE);
				et_phone_2.setText(numbers[1]);

				et_phone_3 = (EditText) this.findViewById(R.id.et_phone_3);
				View v1 = (View) et_phone_3.getParent();
				v1.setVisibility(View.VISIBLE);
				et_phone_3.setText(numbers[2]);
			}

			// et_address.setText(entry.m);
			// et_email.setText(contact.getEmail());

			if (0 == entry.photoId) {
				btn_img.setImageResource(R.drawable.default_contact_photo);
			} else {
				Uri uri = ContentUris.withAppendedId(
						ContactsContract.Contacts.CONTENT_URI,
						Integer.parseInt(entry.mID));
				InputStream input = ContactsContract.Contacts
						.openContactPhotoInputStream(this.getContentResolver(),
								uri);
				Bitmap contactPhoto = BitmapFactory.decodeStream(input);
				contactPhotos = contactPhoto;
				btn_img.setImageBitmap(contactPhoto);
			}
		}
	}

	public void findId() {
		btn_contact_back = (Button) this.findViewById(R.id.btn_contact_back);
		btn_contact_title = (TextView) this
				.findViewById(R.id.btn_contact_title);
		btn_save_contact = (Button) this.findViewById(R.id.btn_save_contact);

		et_name = (EditText) this.findViewById(R.id.et_name);
		btn_img = (ImageButton) this.findViewById(R.id.btn_img);
		et_phone = (EditText) this.findViewById(R.id.et_phone);
		et_email = (EditText) this.findViewById(R.id.et_email);
		et_address = (EditText) this.findViewById(R.id.et_address);
		sp_group = (Spinner) this.findViewById(R.id.sp_group);

		add_phone_row_btn = (ImageButton) this.findViewById(R.id.add_phone_row);
	}

	int count = 0;

	@Override
	protected void onResume() {
		super.onResume();

		new Thread(runnable).start();

		// Ìí¼Óµç»°ÐÐ
		add_phone_row_btn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				count++;
				if (count == 1) {// µÚÒ»´Îµã»÷Ê±
					add_phone_row_btn_2 = (ImageButton) AddContactActivity.this
							.findViewById(R.id.add_phone_row_2);
					et_phone_2 = (EditText) AddContactActivity.this
							.findViewById(R.id.et_phone_2);
					View v1 = (View) et_phone_2.getParent();
					v1.setVisibility(View.VISIBLE);
					// Ìí¼ÓÉ¾³ýÊÂ¼þ¼àÌý
					add_phone_row_btn_2
							.setOnClickListener(new OnClickListener() {
								@Override
								public void onClick(View v) {
									View v1 = (View) add_phone_row_btn_2
											.getParent();
									v1.setVisibility(View.GONE);
									count--;
								}
							});
				}
				if (count == 2) {// µ±µÚ¶þ´Îµã»÷Ìí¼ÓÐÐÊ±
					add_phone_row_btn_3 = (ImageButton) AddContactActivity.this
							.findViewById(R.id.add_phone_row_3);
					et_phone_3 = (EditText) AddContactActivity.this
							.findViewById(R.id.et_phone_3);
					View v2 = (View) et_phone_3.getParent();
					v2.setVisibility(View.VISIBLE);
					// Ìí¼ÓÉ¾³ýÊÂ¼þ¼àÌý
					add_phone_row_btn_3
							.setOnClickListener(new OnClickListener() {
								@Override
								public void onClick(View v) {
									View v1 = (View) add_phone_row_btn_3
											.getParent();
									v1.setVisibility(View.GONE);
									count--;
								}
							});
				}
			}
		});

		// Í·ÏñÑ¡Ôñ
		btn_img.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				showChooseDialog();
			}
		});

		// ±£´æ
		btn_save_contact.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {

				if (loadlag != 1) {
					Toast.makeText(getApplicationContext(), "Èº×é²»ÄÜÎª¿Õ",
							Toast.LENGTH_SHORT).show();
					return;
				}
				String groupName = sp_group.getSelectedItem().toString();
				if (TextUtils.isEmpty(groupName)) {// µ±Èº×éÃ»ÓÐ¼ÓÔØ³öÀ´Ê±ÓÃ»§µã»÷ÐÞ¸Äµ¯³öµÄÌáÊ¾
					Toast.makeText(getApplicationContext(), "ÐÕÃû²»ÄÜÎª¿Õ",
							Toast.LENGTH_SHORT).show();
					return;
				}
				int groupId = new GroupDAO(AddContactActivity.this)
						.getIdByGroupName(groupName);
				SortEntry contact = new SortEntry();
				// »ñÈ¡ÐÕÃû
				String name = et_name.getText().toString();
				// String address = et_address.getText().toString();
				// String email = et_email.getText().toString();
				if (TextUtils.isEmpty(name)) {
					Toast.makeText(AddContactActivity.this, "ÐÕÃû²»ÄÜÎª¿Õ",
							Toast.LENGTH_SHORT).show();
					return;
				}

				contact.mName = name;
				// »ñÈ¡ÊÖ»úºÅÂë
				String mobilePhone = et_phone.getText().toString();
				// ¶ÔÊÖ»úºÅÂëµÄ¸öÊý½øÐÐÅÐ¶Ï£¬
				// Èç¹ûÌí¼ÓÁËÒ»ÐÐ£¬¾Í»ñÈ¡Ò»´Î
				// Èç¹ûÌí¼ÓÁËÁ½ÐÐ£¬¾Í»ñÈ¡Á½´Î
				// ÕâÀïÖ»ÄÜÌí¼ÓÁ½ÐÐ
				if (et_phone_2 != null) {
					String mobilePhone_2 = et_phone_2.getText().toString()
							.trim();
					mobilePhone += "#" + mobilePhone_2;
				} else if (et_phone_3 != null) {
					String mobilePhone_2 = et_phone_2.getText().toString()
							.trim();
					String mobilePhone_3 = et_phone_3.getText().toString()
							.trim();
					mobilePhone += "#" + mobilePhone_2 + "#" + mobilePhone_3;
				}
				contact.mNum = mobilePhone;
				if (contactPhotos != null) {
					contact.contactPhoto = contactPhotos;
				}

				if (groupName == "ÎÞ") {
					groupId = 0;
				}
				contact.groupId = groupId;
				if (flag == 0) {
					new AddContactTask(contact, groupId).execute();
				} else {
					contact.mID = entry.mID;
					new UpdateContactTask(contact, entry.groupId).execute();
				}
			}
		});

		// ·µ»Ø
		btn_contact_back.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				finish();
			}
		});
	}

	@Override
	protected void onStart() {
		super.onStart();
	}

	// ¿ÉÒÔ¶à´ÎÔËÐÐ,ÉèÖÃÈº×éÐÅÏ¢
	private Runnable runnable = new Runnable() {
		@Override
		public void run() {
			GroupDAO gp = new GroupDAO(AddContactActivity.this);
			groupList = gp.getGroups();
			handler.sendEmptyMessage(0);
		}
	};
	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 0:
				ArrayAdapter<String> adapter3 = setAdapterGroup(groupList);// ·¢ËÍÏûÏ¢Í¨ÖªListView¸üÐÂ
				sp_group.setAdapter(adapter3); // ÖØÐÂÉèÖÃListViewµÄÊý¾ÝÊÊÅäÆ÷
				if (flag == 1) {
					Tools.setSpinnerItemSelectedByValue(sp_group, groupName);
				}
				loadlag = 1;// Èº×éÐÅÏ¢¼ÓÔØ×´Ì¬ 1´ú±í¼ÓÔØÍê³É
				break;
			default:
				break;
			}
		}
	};

	public ArrayAdapter<String> setAdapterGroup(List<GroupBean> list) {
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		adapter.add("ÎÞ");
		for (GroupBean bean : list) {
			adapter.add(bean.getName());
		}
		return adapter;
	}

	private AlertDialog dialog;

	/**
	 * ÏÔÊ¾Ñ¡Ôñ¶Ô»°¿ò ×Ô¶¨Òå¶Ô»°¿ò·ç¸ñ
	 */
	String[] items = {"ÅÄÕÕ","´ÓÍ¼¿âÑ¡Ôñ"};
	@SuppressLint("InflateParams")
	private void showChooseDialog() {

		dialog = new AlertDialog.Builder(this)
				.setTitle("ÉèÖÃÍ·Ïñ")
				.setItems(items, new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						switch (which) {
						case 1:
							Intent intentFromGallery = new Intent();
							intentFromGallery.setType("image/*"); // ÉèÖÃÎÄ¼þÀàÐÍ
							intentFromGallery
									.setAction(Intent.ACTION_GET_CONTENT);
							startActivityForResult(intentFromGallery,
									IMAGE_REQUEST_CODE);
							break;
						case 0:
							Intent intentFromCapture = new Intent(
									MediaStore.ACTION_IMAGE_CAPTURE);
							// ÅÐ¶Ï´æ´¢¿¨ÊÇ·ñ¿ÉÒÔÓÃ£¬¿ÉÓÃ½øÐÐ´æ´¢
							if (Tools.hasSdcard()) {
								intentFromCapture.putExtra(
										MediaStore.EXTRA_OUTPUT,
										Uri.fromFile(new File(Environment
												.getExternalStorageDirectory(),
												IMAGE_FILE_NAME)));
							}

							startActivityForResult(intentFromCapture,
									CAMERA_REQUEST_CODE);
							break;
						}
					}
				})
				.setNegativeButton("È¡Ïû", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				}).create();
		dialog.show();
		// Window window = dialog.getWindow();
		// // ×Ô¶¨ÒåalertdialogµÄÑùÊ½
		// LayoutInflater inflater = this.getLayoutInflater();
		// View view = inflater.inflate(R.layout.show_choose_photo_dialog,
		// null);
		// window.setContentView(view);
		// // ×Ô¶¨ÒåalertdialogµÄÎ»ÖÃ
		// LayoutParams lp = window.getAttributes();
		// lp.y = -50;
		// lp.width = 300;
		// lp.height = 230;
		// window.setAttributes(lp);
		// dialog.setCanceledOnTouchOutside(true);
		// // ÉèÖÃ°´Å¥µã»÷ÊÂ¼þ
		// TextView take_photo_tv = (TextView)
		// view.findViewById(R.id.take_photo);
		// TextView choose_glary_tv = (TextView) view
		// .findViewById(R.id.choose_glary);
		//
		// imagebtn_camera = (ImageButton)
		// view.findViewById(R.id.imagebtn_camera);
		// imagebtn_glary = (ImageButton)
		// view.findViewById(R.id.imagebtn_glary);
		//
		// // ÉèÖÃ°´Å¥ÒÔ¼°ÎÄ×ÖµÄµã»÷ÊÂ¼þ£¬ÅÐ¶ÏÊÇÅÄÕÕÑ¡ÔñÍ·Ïñ»¹ÊÇ´ÓÍ¼¿âÑ¡Ôñ
		// imagebtn_camera.setOnClickListener(new PhotoListener());
		// take_photo_tv.setOnClickListener(new PhotoListener());
		// imagebtn_glary.setOnClickListener(new PhotoListener());
		// choose_glary_tv.setOnClickListener(new PhotoListener());
	}

	// Ñ¡ÔñÍ·Ïñµã»÷ÊÂ¼þ
//	private class PhotoListener implements OnClickListener {
//
//		@Override
//		public void onClick(View v) {
//			switch (v.getId()) {
//			case R.id.take_photo:
//			case R.id.imagebtn_camera:
//				dialog.dismiss();
//				Intent intentFromCapture = new Intent(
//						MediaStore.ACTION_IMAGE_CAPTURE);
//				// ÅÐ¶Ï´æ´¢¿¨ÊÇ·ñ¿ÉÒÔÓÃ£¬¿ÉÓÃ½øÐÐ´æ´¢
//				if (Tools.hasSdcard()) {
//					intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, Uri
//							.fromFile(new File(Environment
//									.getExternalStorageDirectory(),
//									IMAGE_FILE_NAME)));
//				}
//				startActivityForResult(intentFromCapture, CAMERA_REQUEST_CODE);
//				break;
//			case R.id.choose_glary:
//			case R.id.imagebtn_glary:
//				dialog.dismiss();
//				Intent intentFromGallery = new Intent();
//				intentFromGallery.setType("image/*"); // ÉèÖÃÎÄ¼þÀàÐÍ
//				intentFromGallery.setAction(Intent.ACTION_GET_CONTENT);
//				startActivityForResult(intentFromGallery, IMAGE_REQUEST_CODE);
//				break;
//			}
//		}
//	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// ½á¹ûÂë²»µÈÓÚÈ¡ÏûÊ±ºò
		if (resultCode != RESULT_CANCELED) {

			switch (requestCode) {
			case IMAGE_REQUEST_CODE:// Í¼¿â
				startPhotoZoom(data.getData());
				break;
			case CAMERA_REQUEST_CODE:// Ïà»ú
				if (Tools.hasSdcard()) {
					File tempFile = new File(
							Environment.getExternalStorageDirectory(),
							IMAGE_FILE_NAME);
					startPhotoZoom(Uri.fromFile(tempFile));
				} else {
					Toast.makeText(AddContactActivity.this, "Î´ÕÒµ½´æ´¢¿¨£¬ÎÞ·¨´æ´¢ÕÕÆ¬£¡",
							Toast.LENGTH_LONG).show();
				}

				break;
			case RESULT_REQUEST_CODE:// ·µ»ØÖµ
				if (data != null) {
					contactPhotos = new ImageConvert().getImageToView(
							AddContactActivity.this, data, btn_img);
				}
				break;
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	/**
	 * ²Ã¼ôÍ¼Æ¬·½·¨ÊµÏÖ
	 * 
	 * @param uri
	 */
	public void startPhotoZoom(Uri uri) {

		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(uri, "image/*");
		// ÉèÖÃ²Ã¼ô
		intent.putExtra("crop", "true");
		// aspectX aspectY ÊÇ¿í¸ßµÄ±ÈÀý
		intent.putExtra("aspectX", 1);
		intent.putExtra("aspectY", 1);
		// outputX outputY ÊÇ²Ã¼ôÍ¼Æ¬¿í¸ß
		intent.putExtra("outputX", 320);
		intent.putExtra("outputY", 320);
		intent.putExtra("return-data", true);
		startActivityForResult(intent, 2);
	}

	// ±£´æÁªÏµÈË
	private class AddContactTask extends AsyncTask<Void, Integer, Void> {

		private SortEntry be;
		private int groupId;

		public AddContactTask(SortEntry be, int groupId) {
			this.be = be;
			this.groupId = groupId;
		}

		@Override
		protected Void doInBackground(Void... params) {
			if (!TextUtils.isEmpty(be.mName)) {
				System.out.println(be.mNum);
				cat = new ContactDAO(getApplicationContext());
				cat.addContact1(be, groupId);
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			if (m_dialogLoading != null) {
				finish();
				// contactFlag = 2;//ÁªÏµÈË·¢ÉúÁË±ä»¯
				m_dialogLoading.dismiss();
			}
		}

		@Override
		protected void onPreExecute() {
			m_dialogLoading = new ProgressDialog(AddContactActivity.this);
			m_dialogLoading.setProgressStyle(ProgressDialog.STYLE_SPINNER);// ÉèÖÃ·ç¸ñÎªÔ²ÐÎ½ø¶ÈÌõ
			m_dialogLoading.setMessage("ÕýÔÚ±£´æ...");
			m_dialogLoading.setCancelable(false);
			m_dialogLoading.show();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
		}
	}

	private class UpdateContactTask extends AsyncTask<Void, Integer, Void> {

		private SortEntry be;
		private int old_groupID;

		public UpdateContactTask(SortEntry be, int old_groupID) {
			this.be = be;
			this.old_groupID = old_groupID;
		}

		@Override
		protected Void doInBackground(Void... params) {
			ContactDAO contactDAO = new ContactDAO(AddContactActivity.this);
			int raw_contact_id = Integer.parseInt(be.mID);
			System.out.println(be.mID + "  " + be.mName + " " + be.mNum + " "
					+ be.contactPhoto);
			if (groupFlag == 1 && photoFlag == 1) {// ÁªÏµÈËÒÑ¾­´æÔÚÍ·ÏñÒÑ·Ö×é-
				System.out.println("1");
				contactDAO.updataCotact(raw_contact_id, be, old_groupID);
			} else if (groupFlag == 0 && photoFlag == 1) {// ÁªÏµÈËÎ´·Ö×é¡¢Í·Ïñ´æÔÚ-
				System.out.println("2");
				contactDAO.updataCotactNoGroup(raw_contact_id, be);
			} else if (groupFlag == 1 && photoFlag == 0) {// ÁªÏµÈËÒÑ·Ö×é¡¢Í·Ïñ²»´æÔÚ
				System.out.println("3");
				contactDAO.updataCotactNoPhoto(raw_contact_id, be, old_groupID);
			} else {// ÁªÏµÈËÍ·Ïñ²»´æÔÚ¡¢Î´·Ö×é-
				System.out.println("4");
				contactDAO.updataCotactNoG_Photo(raw_contact_id, be);
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			if (m_dialogLoading != null) {
				finish();
				Intent intent = new Intent();
				intent.setClass(AddContactActivity.this,
						ContactDetialActivity.class);
				Bundle bundle = new Bundle();
				bundle.putParcelable(Parameter.CONTACT_DETIAL_KEY, be);
				intent.putExtra("type", Parameter.CONTACT_DETIAL_TYPE);
				intent.putExtras(bundle);
				startActivity(intent);
				m_dialogLoading.dismiss();
			}
		}

		@Override
		protected void onPreExecute() {
			m_dialogLoading = new ProgressDialog(AddContactActivity.this);
			m_dialogLoading.setProgressStyle(ProgressDialog.STYLE_SPINNER);// ÉèÖÃ·ç¸ñÎªÔ²ÐÎ½ø¶ÈÌõ
			m_dialogLoading.setMessage("ÕýÔÚ±£´æ...");
			m_dialogLoading.setCancelable(false);
			m_dialogLoading.show();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
		}
	}

} @SuppressLint("HandlerLeak")
public class AddRemoveContactGroup extends Activity{
	
	// ×îÉÏÃæµÄlayout
	private RelativeLayout acbuwa_topbar;
	//×ÖÄ¸ÁÐÊÓÍ¼View
	private AlphabetScrollBar asb;
	//ÏÔÊ¾Ñ¡ÖÐµÄ×ÖÄ¸
	private TextView letterNotice;
	//ÁªÏµÈËµÄÁÐ±í
	private ListView contactslist;
	//ÁªÏµÈËÁÐ±íµÄÊÊÅäÆ÷
	private ContactsCursorAdapter contactsAdapter;
	//¼ÓÔØÆ÷¼àÌýÆ÷
	private ContactsLoaderListener m_loaderCallback = new ContactsLoaderListener();
	private String type;//²Ù×÷ÀàÐÍ
	private int groupID;
	//ËùÓÐÁªÏµÈËµÄÊý¾Ýlist
	private ArrayList<SortEntry> sortList = new ArrayList<SortEntry>();
	//É¸Ñ¡²éÑ¯ºóµÄÊý¾Ýlist
	private ArrayList<SortEntry> filterList = new ArrayList<SortEntry>();
	// ËÑË÷¹ýÂËÁªÏµÈËEditText
	private EditText filterEditText;
	// É¸Ñ¡ºóµÄÊÊÅäÆ÷
	private FilterAdapter fAdapter;
	//Ñ¡ÖÐ¶àÉÙ¸öÐèÒªÉ¾³ýµÄÁªÏµÈË
	private int choosenum=0;
	//ÅúÁ¿É¾³ý°´Å¥
	private Button sureNumBtn;
	private TextView txtAddContactToGroup_Title;
	//Ã»ÓÐÆ¥ÅäÁªÏµÈËÊ±ÏÔÊ¾µÄTextView
	private TextView listEmptyText;
	//Ñ¡ÖÐÈ«²¿°´Å¥
	private Button selectAllBtn;
	//Ñ¡ÔñËùÓÐÁªÏµÈËµÄ±êÖ¾
	private boolean selectAll = false;
	//idµÄÊý×é
	private ArrayList<String> chooseContactsID = new ArrayList<String>();
	private ProgressDialog m_dialogLoading;
	private SortCursor contactsCursor;
	
	private ImageButton imbAddContactToGroup_Back;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_add_contact_to_group);
		
		txtAddContactToGroup_Title = (TextView) this.findViewById(R.id.txtAddContactToGroup_Title);
		type = getIntent().getExtras().getString("type");
		groupID = getIntent().getExtras().getInt("groupID");
		
		//µÃµ½ÁªÏµÈËÁÐ±í,²¢ÉèÖÃÊÊÅäÆ÷
		getLoaderManager().initLoader(0,null,m_loaderCallback);
		contactslist = (ListView)findViewById(R.id.pb_listvew);
		contactsAdapter = new ContactsCursorAdapter(this, null);
		contactsAdapter.setData(sortList);
		contactslist.setAdapter(contactsAdapter);
		
		//µÃµ½×ÖÄ¸ÁÐµÄ¶ÔÏó,²¢ÉèÖÃ´¥ÃþÏìÓ¦¼àÌýÆ÷
		asb = (AlphabetScrollBar)findViewById(R.id.fast_scroller);
		asb.setOnTouchBarListener(new ScrollBarListener());
		letterNotice = (TextView)findViewById(R.id.fast_position);
		asb.setTextView(letterNotice);
				
		listEmptyText = (TextView)findViewById(R.id.nocontacts_notice);
		acbuwa_topbar = (RelativeLayout)findViewById(R.id.acbuwa_topbar);
		sureNumBtn = (Button)findViewById(R.id.sure_num);
		selectAllBtn = (Button)findViewById(R.id.select_all);
		
		//³õÊ¼»¯ËÑË÷±à¼­¿ò,ÉèÖÃÎÄ±¾¸Ä±äÊ±µÄ¼àÌýÆ÷
		filterEditText = (EditText)findViewById(R.id.pb_search_edit);
		
		imbAddContactToGroup_Back = (ImageButton) this.findViewById(R.id.imbAddContactToGroup_Back);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		if(type.equals("add")){
			Tools.Toast(AddRemoveContactGroup.this,type);
			txtAddContactToGroup_Title.setText("ÏòÈº×éÌí¼Ó³ÉÔ±");
		}else{
			Tools.Toast(AddRemoveContactGroup.this,type);
			txtAddContactToGroup_Title.setText("´ÓÈº×éÒÆ³ý³ÉÔ±");
		}
		//·µ»Ø
		imbAddContactToGroup_Back.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				finish();
			}
		});
		
		// ËÑË÷ÁªÏµÈË
		filterEditText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {

				if (!"".equals(s.toString().trim())) {
					// ¸ù¾Ý±à¼­¿òÖµ¹ýÂËÁªÏµÈË²¢¸üÐÂÁªÏµÁÐ±í
//					SortCursor contactsCursor = (SortCursor) contactsAdapter.getCursor();
//					getContactCursor();
					filterList = contactsCursor.filterSearch1(s.toString().trim(),sortList);

					fAdapter = new FilterAdapter(AddRemoveContactGroup.this, filterList);
					contactslist.setAdapter(fAdapter);
				} else {
					contactslist.setAdapter(contactsAdapter);
				}
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {

			}
		});
				
		//ÁªÏµÈËµã»÷ÊÂ¼þ¼àÌý£¬µã»÷¾ÍÑ¡ÖÐ»òÕß·´Ñ¡
		contactslist.setOnItemClickListener(new OnItemClickListener()
		{

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				if(sortList.get(arg2).mchoose == 0)
				{
					sortList.get(arg2).mchoose = 1;
					choosenum++;
					chooseContactsID.add(sortList.get(arg2).mID);
				}
				else
				{
					sortList.get(arg2).mchoose = 0;
					for(int i=0;i<choosenum;i++)
					{
						if(chooseContactsID.get(i).equals(sortList.get(arg2).mID))
						{
							chooseContactsID.remove(i);
							break;
						}
					}
					choosenum--;
				}
				
				contactsAdapter.notifyDataSetChanged();
				sureNumBtn.setText("È·¶¨("+ choosenum +")");
			}
		});
		
		//È·¶¨°´Å¥ºÍÑ¡ÔñÈ«²¿°´Å¥
		sureNumBtn.setOnClickListener(new BtnClick());
		selectAllBtn.setOnClickListener(new BtnClick());
	}
	
	private class BtnClick implements View.OnClickListener{

		@Override
		public void onClick(View v) {
			if(v.getId() == R.id.sure_num)
			{
				if(choosenum>0)
				{
					if(type.equals("add")){
						new AddContactToGTask(groupID).execute();
					}else if(type.equals("remove")){
						new RemoveContactFromGTask(groupID).execute();
					}
				}
				else
				{
					Tools.Toast(AddRemoveContactGroup.this,"ÇëÑ¡ÔñÒª"+Tools.pinYinToHanZi(type)+"µÄÁªÏµÈË");
				}
			}
			else if(v.getId() == R.id.select_all)
			{
				chooseContactsID.clear();
				if(!selectAll)
				{
					for(int i=0;i<sortList.size();i++)
					{
						sortList.get(i).mchoose = 1;
						chooseContactsID.add(sortList.get(i).mID);
					}
					choosenum = sortList.size();
					sureNumBtn.setText("È·¶¨("+ sortList.size() +")");
					selectAllBtn.setText("È¡ÏûÈ«²¿");
					contactsAdapter.notifyDataSetChanged();
					selectAll = !selectAll;
				}
				else
				{
					for(int i=0;i<sortList.size();i++)
					{
						sortList.get(i).mchoose = 0;
					}
					choosenum = 0;
					sureNumBtn.setText("È·¶¨(0)");
					selectAllBtn.setText("Ñ¡ÔñÈ«²¿");
					contactsAdapter.notifyDataSetChanged();
					selectAll = !selectAll;
				}
			}
		}
	}
	
	// ¼ÓÔØÆ÷µÄ¼àÌýÆ÷
	private class ContactsLoaderListener implements
			LoaderManager.LoaderCallbacks<Cursor> {

		@Override
		public Loader<Cursor> onCreateLoader(int id, Bundle args) {
			return new SortCursorLoader(AddRemoveContactGroup.this,
					ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
					null, null, null);
		}

		@Override
		public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
			contactsAdapter.swapCursor(arg1);
//			new LoadAnysTack().execute();
			contactsCursor = (SortCursor) contactsAdapter.getCursor();
			if (acbuwa_topbar.getVisibility() == View.VISIBLE) {
				if(type.equals("add")){
					sortList  = contactsCursor.getAddContactsArray(groupID);
				}else{
					sortList  = contactsCursor.getRemoveContactsArray(groupID);
				}
				contactsAdapter.setData(sortList);
				contactslist.setAdapter(contactsAdapter);
			}else {
				filterList = contactsCursor.filterSearch(filterEditText.getText()
						.toString().trim());
				fAdapter = new FilterAdapter(AddRemoveContactGroup.this, filterList);
				contactslist.setAdapter(fAdapter);
			}
		}
		@Override
		public void onLoaderReset(Loader<Cursor> arg0) {
			contactsAdapter.swapCursor(null);
		}
	}
	
	//×ÖÄ¸ÁÐ´¥ÃþµÄ¼àÌýÆ÷
	private class ScrollBarListener implements AlphabetScrollBar.OnTouchBarListener {

		@Override
		public void onTouch(String letter) {
			
			//´¥Ãþ×ÖÄ¸ÁÐÊ±,½«ÁªÏµÈËÁÐ±í¸üÐÂµ½Ê××ÖÄ¸³öÏÖµÄÎ»ÖÃ
//			contactsCursor = (SortCursor)contactsAdapter.getCursor();
//			getContactCursor();
			if(contactsCursor != null) 
			{
				int idx = contactsCursor.binarySearch(letter);
				if(idx != -1)
				{
					contactslist.setSelection(idx);
				}
			}
		}
	}
	
	private class ContactsCursorAdapter extends CursorAdapter{
		private Context context;
		private ArrayList<SortEntry> lists;
		@SuppressWarnings("deprecation")
		public ContactsCursorAdapter(Context context, Cursor c) {
			super(context, c);
			this.context = context;
		}
		public void setData(ArrayList<SortEntry> entryLists){
			this.lists = entryLists;
		}
		
		@Override
		public SortEntry getItem(int position) {
			return sortList.get(position);
		}

		@Override
		public int getCount() {
			return sortList.size();
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if(convertView == null)
			{
				convertView = LayoutInflater.from(context).inflate(R.layout.list_item_add_remove_contact, parent, false);
			}
			
			ImageView photo = (ImageView) convertView.findViewById(R.id.contact_photo);
	        
	        int photoId = lists.get(position).photoId;
	        String contactID = lists.get(position).mID;
	        if(0 == photoId){
	        	photo.setImageResource(R.drawable.default_contact_photo);
	        }else{
	        	Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,Integer.parseInt(contactID));
				InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), uri); 
				Bitmap contactPhoto = BitmapFactory.decodeStream(input);
				photo.setImageBitmap(contactPhoto);
	        }
	        
            TextView name = (TextView) convertView.findViewById(R.id.contacts_name);
            name.setText(lists.get(position).mName);
			if(lists.get(position).mchoose == 1)
			{
				ImageView choosecontact = (ImageView)convertView.findViewById(R.id.choose_contact);
				choosecontact.setImageResource(R.drawable.cb_checked);
			}
			else
			{
				ImageView choosecontact = (ImageView)convertView.findViewById(R.id.choose_contact);
				choosecontact.setImageResource(R.drawable.cb_unchecked);
			}

			return convertView;
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			if(cursor == null)
			{
				return;
			}
			
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			return LayoutInflater.from(context).inflate(R.layout.list_item_home_contacts, parent, false);
		}
		
	}
	
	
	/**
	 * Ìí¼Ó³ÉÔ±µ½Èº×é
	 * 
	 * @author NightHary
	 * 
	 */
	private class AddContactToGTask extends AsyncTask<Void, Void, ArrayList<SortEntry>> {
		int groupID;

		public AddContactToGTask(int groupID) {
			this.groupID = groupID;
		}

		@Override
		protected ArrayList<SortEntry> doInBackground(Void... params) {
			ArrayList<SortEntry> entrys;
			for(String contactId : chooseContactsID){
				new GroupDAO(AddRemoveContactGroup.this).addMemberToGroup(Integer.parseInt(contactId),groupID);
			}
		//	contactsCursor = (SortCursor) contactsAdapter.getCursor();
			if(type.equals("add")){
				entrys  = contactsCursor.getAddContactsArray(groupID);
			}else{
				entrys  = contactsCursor.getRemoveContactsArray(groupID);
			}
			return entrys;
		}

		@Override
		protected void onPostExecute(ArrayList<SortEntry> result) {
			super.onPostExecute(result);
			if (m_dialogLoading != null) {
				if(result.isEmpty()){
					listEmptyText.setVisibility(View.VISIBLE);
				}
				contactsAdapter.setData(result);
				contactslist.setAdapter(contactsAdapter);
				contactsAdapter.notifyDataSetChanged();
				sureNumBtn.setText("È·¶¨(0)");
				choosenum = 0;
				try {
					Thread.sleep(8000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				m_dialogLoading.dismiss();
			}
		}

		@Override
		protected void onPreExecute() {
			m_dialogLoading = new ProgressDialog(AddRemoveContactGroup.this);
			m_dialogLoading.setProgressStyle(ProgressDialog.STYLE_SPINNER);// ÉèÖÃ·ç¸ñÎªÔ²ÐÎ½ø¶ÈÌõ
			m_dialogLoading.setMessage("ÕýÔÚÌí¼Ó...");
			m_dialogLoading.setCancelable(false);
			m_dialogLoading.show();
		}
	}

	/**
	 * ´ÓÈº×éÒÆ³ý³ÉÔ±
	 * 
	 * @author NightHary
	 * 
	 */
	private class RemoveContactFromGTask extends AsyncTask<Void, Void, ArrayList<SortEntry>> {
		int groupID;
		
		public RemoveContactFromGTask(int groupID) {
			this.groupID = groupID;
		}

		@Override
		protected ArrayList<SortEntry> doInBackground(Void... params) {
			ArrayList<SortEntry> entrys;
			for(String contactId : chooseContactsID){
				new GroupDAO(AddRemoveContactGroup.this).deleteMemberFromGroup(Integer.parseInt(contactId),groupID);
			}
			contactsCursor = (SortCursor) contactsAdapter.getCursor();
			if(type.equals("add")){
				entrys  = contactsCursor.getAddContactsArray(groupID);
			}else{
				entrys  = contactsCursor.getRemoveContactsArray(groupID);
			}
			return entrys;
		}

		@Override
		protected void onPostExecute(ArrayList<SortEntry> result) {
			super.onPostExecute(result);
			if (m_dialogLoading != null) {
				if(result.isEmpty()){
					listEmptyText.setVisibility(View.VISIBLE);
				}
				contactsAdapter.setData(result);
				contactslist.setAdapter(contactsAdapter);
				contactsAdapter.notifyDataSetChanged();
				sureNumBtn.setText("È·¶¨(0)");
				choosenum = 0;
				try {
					Thread.sleep(8000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				m_dialogLoading.dismiss();
			}
		}

		@Override
		protected void onPreExecute() {
			m_dialogLoading = new ProgressDialog(AddRemoveContactGroup.this);
			m_dialogLoading.setProgressStyle(ProgressDialog.STYLE_SPINNER);// ÉèÖÃ·ç¸ñÎªÔ²ÐÎ½ø¶ÈÌõ
			m_dialogLoading.setMessage("ÕýÔÚÒÆ³ý...");
			m_dialogLoading.setCancelable(false);
			m_dialogLoading.show();
		}
	}
} @SuppressLint("ClickableViewAccessibility")
public class AlphabetScrollBar extends View {

	private Paint mPaint = new Paint();
	private String[] mAlphabet = new String[] {
		"#","A", "B", "C", "D", "E", "F", "G","H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
		"R", "S", "T", "U", "V", "W", "X", "Y", "Z"
	};
	private boolean mPressed;
	private int mCurPosIdx = -1;
	private int mOldPosIdx = -1;
	private OnTouchBarListener mTouchListener;
	private TextView LetterNotice;

	public AlphabetScrollBar(Context arg0, AttributeSet arg1, int arg2) {
		super(arg0, arg1, arg2);
	}

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

	public AlphabetScrollBar(Context context) {
		super(context);
	}
	
	public void setTextView(TextView LetterNotice) {
		this.LetterNotice = LetterNotice;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		int width = this.getWidth();
		int height = this.getHeight();
		
		int singleLetterH = height/mAlphabet.length;
		
		if(mPressed) {
			//Èç¹û´¦ÓÚ°´ÏÂ×´Ì¬£¬¸Ä±ä±³¾°¼°ÏàÓ¦×ÖÌåµÄÑÕÉ«
			canvas.drawColor(Color.parseColor("#40000000"));
		}
		
		for(int i=0; i<mAlphabet.length; i++) {
			mPaint.setColor(Color.parseColor("#000000"));
			mPaint.setAntiAlias(true);
			mPaint.setTextSize(23);
			
			float x = width/2 - mPaint.measureText(mAlphabet[i])/2;
			float y = singleLetterH*i+singleLetterH;
			
			if(i == mCurPosIdx)
			{
				mPaint.setColor(Color.parseColor("#0000FF"));
				mPaint.setFakeBoldText(true);
			}
			canvas.drawText(mAlphabet[i], x, y, mPaint);
			mPaint.reset();
		}

	}

	@Override
	public boolean onTouchEvent(MotionEvent arg0) {

		int action = arg0.getAction();
		switch(action) {
		case MotionEvent.ACTION_DOWN:
			mPressed = true;
			mCurPosIdx =(int)( arg0.getY()/this.getHeight() * mAlphabet.length);
			if(mTouchListener != null && mOldPosIdx!=mCurPosIdx){
				if((mCurPosIdx>=0) && (mCurPosIdx<mAlphabet.length)) {
					mTouchListener.onTouch(mAlphabet[mCurPosIdx]);
					this.invalidate();
				}
				mOldPosIdx = mCurPosIdx;
			}
			
			LetterNotice.setText(mAlphabet[mCurPosIdx]);
			LetterNotice.setVisibility(View.VISIBLE);
			
			return true;
		case MotionEvent.ACTION_UP:
			
			if (LetterNotice != null) {
				LetterNotice.setVisibility(View.INVISIBLE);
			}
			
			mPressed = false;
			mCurPosIdx = -1;
			this.invalidate();
			return true;
		case MotionEvent.ACTION_MOVE:
			mCurPosIdx =(int)( arg0.getY()/this.getHeight() * mAlphabet.length);
			if(mTouchListener != null && mCurPosIdx!=mOldPosIdx){
				if((mCurPosIdx>=0) && (mCurPosIdx<mAlphabet.length)) {
					mTouchListener.onTouch(mAlphabet[mCurPosIdx]);
					this.invalidate();
				}
				mOldPosIdx = mCurPosIdx;
			}
			
			if(mCurPosIdx >= 0 && mCurPosIdx < mAlphabet.length)
			{
				LetterNotice.setText(mAlphabet[mCurPosIdx]);
				LetterNotice.setVisibility(View.VISIBLE);
			}
			
			return true;
		default:
			return super.onTouchEvent(arg0);
		}
		
	}
	
	/**
	 * ½Ó¿Ú
	 */
	public static interface OnTouchBarListener {
		void onTouch(String letter);
	}
	
	/**
	 * ÏòÍâ¹«¿ªµÄ·½·¨
	 */
	public void setOnTouchBarListener (OnTouchBarListener listener) {
		mTouchListener = listener;
	}
} public class ContactDetialActivity extends Activity {
	
	private Button btn_contact_back;
	private Button btn_editContact;
	
	private TextView tv_contact_group;
	private TextView tv_contact_name;
	private ImageButton btn_contact_photo;
	
	private GroupDAO groupDAO;
	
	private static int contactFlag = 0;
	
	private SortEntry entry;
	//µç»°ºÍ¶ÌÐÅ°´Å¥
	private Button contact_num_btn_1;
	private Button tv_conatct_sms_1;
	//µç»°ºÍ¶ÌÐÅ°´Å¥
	private Button contact_num_btn_2;
	private Button tv_conatct_sms_2;
	//ºÅÂë3
	private Button contact_num_btn_3;
	private Button tv_conatct_sms_3;
	
	private String[] numbers;//µç»°Êý×é
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.contact_detail);
		
		btn_contact_back = (Button) this.findViewById(R.id.btn_contact_back);
		btn_editContact = (Button) this.findViewById(R.id.btn_editContact);
		tv_contact_name = (TextView) this.findViewById(R.id.tv_contact_name);
		tv_contact_group = (TextView) this.findViewById(R.id.tv_contact_group);
		btn_contact_photo = (ImageButton) this.findViewById(R.id.btn_contact_photo);
		groupDAO = new GroupDAO(ContactDetialActivity.this);
		
		contact_num_btn_1  = (Button) this.findViewById(R.id.contact_num_btn_1);
		tv_conatct_sms_1 = (Button) this.findViewById(R.id.tv_conatct_sms_1);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		//»ñÈ¡ÁªÏµÈËÐÅÏ¢²¢ÉèÖÃµ½½çÃæ
		String type = getIntent().getStringExtra("type");
		if(type.equals(Parameter.CONTACT_DETIAL_TYPE)){
			entry = getIntent().getParcelableExtra(Parameter.CONTACT_DETIAL_KEY);
		}
		//ÏÔÊ¾ÐÕÃû
		tv_contact_name.setText(entry.mName);
		//ÏÔÊ¾µç»°ºÅÂë
		String phoneNumber = entry.mNum;
		System.out.println(phoneNumber);
		numbers = Tools.getPhoneNumber(phoneNumber);
		if(numbers.length == 1){//Ö»ÓÐÒ»¸öºÅÂë
			contact_num_btn_1.setText(numbers[0]);
		}else if(numbers.length == 2){//Á½¸öºÅÂë,»ñÈ¡×é¼þ£¬²¢ÉèÖÃºÅÂë
			contact_num_btn_2 = (Button) this.findViewById(R.id.contact_num_btn_2);
			tv_conatct_sms_2 = (Button) this.findViewById(R.id.tv_conatct_sms_2);
			View v = (View) contact_num_btn_2.getParent();
			v.setVisibility(View.VISIBLE);
			contact_num_btn_1.setText(numbers[0]);
			contact_num_btn_2.setText(numbers[1]);
		}else if(numbers.length == 3){//Á½¸öºÅÂë,»ñÈ¡×é¼þ£¬²¢ÉèÖÃºÅÂë
			contact_num_btn_2 = (Button) this.findViewById(R.id.contact_num_btn_2);
			tv_conatct_sms_2 = (Button) this.findViewById(R.id.tv_conatct_sms_2);
			contact_num_btn_3 = (Button) this.findViewById(R.id.contact_num_btn_3);
			tv_conatct_sms_3 = (Button) this.findViewById(R.id.tv_conatct_sms_3);
			View v = (View) contact_num_btn_2.getParent();
			v.setVisibility(View.VISIBLE);
			View v1 = (View) contact_num_btn_3.getParent();
			v1.setVisibility(View.VISIBLE);
			contact_num_btn_1.setText(numbers[0]);
			contact_num_btn_2.setText(numbers[1]);
			contact_num_btn_3.setText(numbers[2]);
		}
		
		//ÉèÖÃÈº×é
		int groupId = new ContactDAO(this).getGroupIdByContactId(Integer.parseInt(entry.mID));
		entry.groupId = groupId;
		String groupName = groupDAO.getGroupNameByGroupId(groupId);
		entry.groupName = groupName;
		if(groupId == 0){
			tv_contact_group.setText("Î´·Ö×é");
		}else{
			tv_contact_group.setText(groupName);
		}
		
		//Í·Ïñ
		if(0 == entry.photoId){
			btn_contact_photo.setImageResource(R.drawable.default_contact_photo);
		}else{
			Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Integer.parseInt(entry.mID));
			InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(this.getContentResolver(), uri); 
			Bitmap contactPhoto = BitmapFactory.decodeStream(input);
			btn_contact_photo.setImageBitmap(contactPhoto);
		}
		
		
		//·µ»Ø
		btn_contact_back.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				ContactDetialActivity.this.finish();
			}
		});
		
		//±à¼­ÁªÏµÈË
		btn_editContact.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
//				contactFlag = 1;
				Intent intent = new Intent();
				Bundle bundle = new Bundle();
				bundle.putString("type",Parameter.CONTACT_EDIT_TYPE);
				bundle.putParcelable(Parameter.CONTACT_EDIT_KEY, entry);
				intent.putExtras(bundle);
				intent.setClass(ContactDetialActivity.this,AddContactActivity.class);
				startActivity(intent);
			}
		});
		
		addListener(contact_num_btn_1,tv_conatct_sms_1,numbers[0]);
		//Èç¹ûÁ½¸öbutton²»Îª¿Õ¼´ÒÑ¾­¸ù¾Ýid»ñÈ¡ÁËÖµ£¬¼´¸ÃÁªÏµÈË´æÔÚÁ½¸öºÅÂë
		if(contact_num_btn_2 != null && tv_conatct_sms_2 != null){
			addListener(contact_num_btn_2,tv_conatct_sms_2,numbers[1]);
		}
		if(contact_num_btn_3 != null && tv_conatct_sms_3 != null){
			addListener(contact_num_btn_3,tv_conatct_sms_3,numbers[2]);
		}
	}

	public static int getContactFlag() {
		return contactFlag;
	}

	public static void setContactFlag(int contactFlag) {
		ContactDetialActivity.contactFlag = contactFlag;
	}
	
	private void addListener(View viewId_phone,View viewId_sms,final String number){
		//²¦´òµç»°
		viewId_phone.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(
						Intent.ACTION_CALL,
						Uri.parse("tel://"
								+ number));
				startActivity(intent);
			}
		});
		//·¢ËÍ¶ÌÐÅ
		viewId_sms.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Uri smsToUri = Uri.parse("smsto://134");
				Intent mIntent = new Intent(Intent.ACTION_SENDTO, smsToUri );
				startActivity(mIntent);
			}
		});
	}
} @SuppressLint("InflateParams")
public class GroupManageActivity extends Activity {

	private ListView grouplist_name;
	private ArrayList<GroupBean> groups;
	private String[] groupClickItem = { "Ìí¼Ó³ÉÔ±", "ÒÆ³ý³ÉÔ±", "ÐÞ¸ÄÃû³Æ", "É¾³ý", "È¡Ïû" };
	private Button btn_group_back;
	private Button btn_addgroup;
	private GroupListAdapter adapter;
	private GroupDAO groupDAO;
	private ProgressDialog m_dialogLoading;
	// ÊäÈëÈº×é¶Ô»°¿ò
	private static int groupFlag = 0;
	private LayoutInflater inflater;
	private AlertDialog.Builder builder;
	private AlertDialog dialog;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.group_manage_page);

		grouplist_name = (ListView) this.findViewById(R.id.grouplist_name);
		groupDAO = new GroupDAO(this);
		inflater = LayoutInflater.from(this);
		// groups = groupDAO.getGroups();

		btn_group_back = (Button) this.findViewById(R.id.btn_group_back);
		btn_addgroup = (Button) this.findViewById(R.id.btn_addgroup);
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void onResume() {
		super.onResume();
		Intent intent = getIntent();
		groups = (ArrayList<GroupBean>) intent.getExtras().getSerializable(
				Parameter.GROUP_LIST);
		groups.remove(0);
		groups.remove(groups.size() - 1);
		adapter = new GroupListAdapter(groups, this);
		grouplist_name.setAdapter(adapter);
	}

	@Override
	protected void onStart() {
		super.onStart();
		// Èº×éµã»÷ÊÂ¼þ
		grouplist_name.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				GroupBean group = groups.get(position);
				showOperateDialog(group);
			}
		});
		// ·µ»Ø°´Å¥µã»÷ÊÂ¼þ
		btn_group_back.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// Intent intent = new Intent();
				// intent.setClass(GroupManageActivity.this,
				// MainActivity.class);
				// startActivity(intent);
				groupFlag = 1;
				finish();
			}
		});
		// Ìí¼ÓÈº×é
		btn_addgroup.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				showMyDialog(5, null);
			}
		});
	}

	// "Ìí¼Ó³ÉÔ±","ÒÆ³ý³ÉÔ±","ÐÞ¸ÄÃû³Æ","É¾³ý","È¡Ïû"
	public void showOperateDialog(final GroupBean group) {
		Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(group.getName())
				.setItems(groupClickItem,
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								if (which == 0) {
									Intent intent = new Intent();
									intent.setClass(GroupManageActivity.this,AddRemoveContactGroup.class);
									intent.putExtra("type","add");
									intent.putExtra("groupID",group.getId());
									startActivity(intent);
								} else if (which == 1) {
									Intent intent = new Intent();
									intent.setClass(GroupManageActivity.this,AddRemoveContactGroup.class);
									intent.putExtra("type","remove");
									intent.putExtra("groupID",group.getId());
									startActivity(intent);
								} else if (which == 2) {
									showMyDialog(2, group);
								} else if (which == 3) {
									showMyDialog(3, group);
								} else if (which == 4) {

								}
							}
						}).show();
	}


	/**
	 * ÏÔÊ¾Ò»¸ö¶Ô»°¿ò
	 * 
	 * @param viewId
	 *            µã»÷µÄµÄÐòºÅ
	 *            0--Ìí¼Ó³ÉÔ±
	 *            1--ÒÆ³ý³ÉÔ±
	 *            2--ÐÞ¸ÄÈº×éÃû³Æ
	 *            3--É¾³ýÈº×é
	 *            4--È¡Ïû
	 *            5--ÐÂ½¨Èº×é
	 * @author NightHary
	 */
	@SuppressLint("DefaultLocale")
	public void showMyDialog(int operateId, final GroupBean group) {

		View dialog_view = inflater.inflate(R.layout.dialog_add_group, null);
		final EditText edtNewGroupName = (EditText) dialog_view
				.findViewById(R.id.edtNewGroupName);
		TextView txtDialogTitleName = (TextView) dialog_view
				.findViewById(R.id.txtNewGroupTitle);
		TextView txtMsgAlert = (TextView) dialog_view
				.findViewById(R.id.txtMsgAlert);
		Button btnSure = (Button) dialog_view.findViewById(R.id.btnAddNewGroup);
		Button btnCancel = (Button) dialog_view
				.findViewById(R.id.btnGroupCancel);

		switch (operateId) {

		case 2:// ·Ö×éÖØÃüÃû
			txtDialogTitleName.setText("±à¼­Ãû³Æ");
			txtMsgAlert.setVisibility(View.GONE);
			edtNewGroupName.setVisibility(View.VISIBLE);
			edtNewGroupName.setHint("ÇëÊäÈëÐÂµÄ·Ö×éÃû³Æ£º");
			edtNewGroupName.setText(group.getName());
			builder = new AlertDialog.Builder(this);
			dialog = builder.setView(dialog_view).create();
			dialog.show();
			btnSure.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					new UpdateGroupTask(edtNewGroupName.getText().toString()
							.trim(), group.getId()).execute();
					dialog.dismiss();
				}
			});
			btnCancel.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					dialog.dismiss();
				}
			});
			break;
		case 3:// É¾³ýÒ»¸ö·Ö×éÊ±ÏÔÊ¾µÄ¶Ô»°¿ò
			txtDialogTitleName.setText("ÎÂÜ°ÌáÊ¾");
			txtMsgAlert.setVisibility(View.VISIBLE);
			txtMsgAlert.setText("È·ÈÏ½âÉ¢·Ö×é'" + group.getName() + "'?");
			edtNewGroupName.setVisibility(View.GONE);
			builder = new AlertDialog.Builder(this);
			dialog = builder.setView(dialog_view).create();
			dialog.show();
			btnSure.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					new DeleteGroupTask(group.getId()).execute();
					dialog.dismiss();
				}
			});
			btnCancel.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					dialog.dismiss();
				}
			});
			break;
		case 4:
			break;
		case 5:// Ìí¼ÓÒ»¸ö·Ö×éÊ±ÏÔÊ¾µÄ¶Ô»°¿ò
			txtDialogTitleName.setText("ÐÂ½¨·Ö×é");
			txtMsgAlert.setVisibility(View.GONE);
			edtNewGroupName.setVisibility(View.VISIBLE);
			edtNewGroupName.setHint("ÇëÊäÈë·Ö×éÃû³Æ£º");
			builder = new AlertDialog.Builder(this);
			dialog = builder.setView(dialog_view).create();
			dialog.show();
			btnSure.setOnClickListener(new OnClickListener() {

				@Override
				public void onClick(View v) {
					new AddGroupTask(edtNewGroupName.getText().toString()
							.trim()).execute();
					dialog.dismiss();
				}
			});
			btnCancel.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					dialog.dismiss();
				}
			});
			break;

		}
	}

	/**
	 * ÐÂÔöÈº×é
	 * 
	 * @author NightHary
	 * 
	 */
	private class AddGroupTask extends AsyncTask<Void, Integer, Void> {
		String groupName;

		public AddGroupTask(String groupName) {
			this.groupName = groupName;
		}

		@Override
		protected Void doInBackground(Void... params) {
			groupDAO.addGroup(groupName);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			if (m_dialogLoading != null) {
				updateGroups();
				m_dialogLoading.dismiss();
				Toast.makeText(GroupManageActivity.this, "Ìí¼Ó³É¹¦",
						Toast.LENGTH_SHORT).show();
			}
		}

		@Override
		protected void onPreExecute() {
			m_dialogLoading = new ProgressDialog(GroupManageActivity.this);
			m_dialogLoading.setProgressStyle(ProgressDialog.STYLE_SPINNER);// ÉèÖÃ·ç¸ñÎªÔ²ÐÎ½ø¶ÈÌõ
			m_dialogLoading.setMessage("ÕýÔÚ±£´æÈº×é...");
			m_dialogLoading.setCancelable(false);
			m_dialogLoading.show();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
		}

	}

	/**
	 * É¾³ýÈº×é
	 * 
	 * @author NightHary
	 * 
	 */
	private class DeleteGroupTask extends AsyncTask<Void, Integer, Void> {
		int groupId;

		public DeleteGroupTask(int groupId) {
			this.groupId = groupId;
		}

		@Override
		protected Void doInBackground(Void... params) {
			groupDAO.deleteGroup(groupId);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			if (m_dialogLoading != null) {
				updateGroups();
				m_dialogLoading.dismiss();
				Toast.makeText(GroupManageActivity.this, "É¾³ý³É¹¦",
						Toast.LENGTH_SHORT).show();
			}
		}

		@Override
		protected void onPreExecute() {
			m_dialogLoading = new ProgressDialog(GroupManageActivity.this);
			m_dialogLoading.setProgressStyle(ProgressDialog.STYLE_SPINNER);// ÉèÖÃ·ç¸ñÎªÔ²ÐÎ½ø¶ÈÌõ
			m_dialogLoading.setMessage("ÕýÔÚÉ¾³ý...");
			m_dialogLoading.setCancelable(false);
			m_dialogLoading.show();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
		}
	}

	private class UpdateGroupTask extends AsyncTask<Void, Integer, Void> {
		String groupName;
		int groupId;

		public UpdateGroupTask(String groupName, int groupId) {
			this.groupName = groupName;
			this.groupId = groupId;
		}

		@Override
		protected Void doInBackground(Void... params) {
			groupDAO.updataGroup(groupId, groupName);
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			if (m_dialogLoading != null) {
				updateGroups();
				m_dialogLoading.dismiss();
				Toast.makeText(GroupManageActivity.this, "ÐÞ¸Ä³É¹¦",
						Toast.LENGTH_SHORT).show();
			}
		}

		@Override
		protected void onPreExecute() {
			m_dialogLoading = new ProgressDialog(GroupManageActivity.this);
			m_dialogLoading.setProgressStyle(ProgressDialog.STYLE_SPINNER);// ÉèÖÃ·ç¸ñÎªÔ²ÐÎ½ø¶ÈÌõ
			m_dialogLoading.setMessage("ÕýÔÚÐÞ¸ÄÈº×é...");
			m_dialogLoading.setCancelable(false);
			m_dialogLoading.show();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
		}
	}

	/**
	 * ¸üÐÂÈº×éÐÅÏ¢
	 * 
	 * @param handler
	 *            Ê¹ÓÃHandlerÀ´´¦ÀíÏß³ÌÓëActivityÖ®¼äµÄÍ¨ÐÅÎÊÌâ¡£ ÓÉÓÚÐèÒª¸üÐÂui£¬ËùÒÔÐèÒªÊ¹ÓÃhandler
	 * @param runnable
	 *            Ê¹ÓÃrunnable£¬¿ÉÒÔÊ¹Õâ¸öÏß³ÌÄÜ¹»¶à´Î¼ÓÔØ
	 */
	@SuppressLint("HandlerLeak")
	private void updateGroups() {
		groups = groupDAO.getGroups();
		adapter.refresh(groups);
	}

	public static int getGroupFlag() {
		return groupFlag;
	}

	public static void setGroupFlag(int groupFlag) {
		GroupManageActivity.groupFlag = groupFlag;
	}
} public class Parameter {
	
	public static String GROUP_LIST = "groupList";
	
	public static String ADD_CONTACT = "addContact";
	
	public static String CONTACT_DETIAL_KEY = "contact_detial_key";
	
	public static String CONTACT_DETIAL_TYPE = "contact_detial_type";
	
	public static String CONTACT_EDIT_KEY = "contact_edit_back_key";
	
	public static String CONTACT_EDIT_TYPE = "contact_edit_back_type";
	
	public static String ADD_CONTACT_TITLE = "ÐÂÔöÁªÏµÈË";
	
	public static String EDIT_CONTACT_TITLE = "±à¼­ÁªÏµÈË";
}
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.LoaderManager;
import android.app.ProgressDialog;
import android.app.Service;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.os.Vibrator;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.night.contact.DAO.ContactDAO;
import com.night.contact.DAO.GroupDAO;
import com.night.contact.adapter.FilterAdapter;
import com.night.contact.adapter.GroupAdapter;
import com.night.contact.bean.GroupBean;
import com.night.contact.bean.SortEntry;
import com.night.contact.contact.ClearEditText;
import com.night.contact.contact.ContactsCursorAdapter;
import com.night.contact.contact.SortCursor;
import com.night.contact.contact.SortCursorLoader;
import com.night.contact.observer.ContactsContentObserver;
import com.night.contact.ui.AddContactActivity;
import com.night.contact.ui.AddRemoveContactGroup;
import com.night.contact.ui.AlphabetScrollBar;
import com.night.contact.ui.ContactDetialActivity;
import com.night.contact.ui.GroupManageActivity;
import com.night.contact.ui.R;
import com.night.contact.util.Parameter;
					contactslist.setAdapter(fAdapter);
				} else {
					contactsAdapter.notifyDataSetChanged();
					contactslist.setAdapter(contactsAdapter);
				}
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {

			}
		});

		// ÁªÏµÈËÁÐ±í³¤°´¼àÌý
		contactslist.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {

				// Õð¶¯
				Vibrator vib = (Vibrator) getActivity().getSystemService(
						Service.VIBRATOR_SERVICE);
				vib.vibrate(50);

				// ½øÐÐÊý¾ÝÅÐ¶Ï£¬Èç¹ûËÑË÷¿òÄÚµÄÖµÎª¿Õ£¬ÔòÏÔÊ¾È«²¿ÁªÏµÈËÁÐ±í
				// Èç¹û²»Îª¿Õ£¬ÔòÏÔÊ¾ËÑË÷listÖÐµÄÊý¾Ý
				if (TextUtils.isEmpty(filterEditText.getText().toString()
						.trim())
						&& (topbar_title_tv.getText().toString().trim()
								.equals("È«²¿") || topbar_title_tv.getText()
								.toString().trim().equals("ÁªÏµÈË"))) {
					SortCursor contactsCursor = (SortCursor) contactsAdapter
							.getCursor();
					chooseContactName = contactsCursor.getName(arg2);
					chooseContactNumber = contactsCursor.getNumber(arg2);
					chooseContactID = contactsCursor.getID(arg2);
				} else {
					chooseContactName = filterList.get(arg2).mName;
					chooseContactNumber = filterList.get(arg2).mNum;
					chooseContactID = filterList.get(arg2).mID;
				}
				showLongClickDialog();
				return false;
			}
		});
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
	}

	@Override
	public void onStart() {
		super.onStart();
	}

	@Override
	public void onPause() {
		super.onPause();

	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
	}

	// ³õÊ¼»¯Èº×é²Ëµ¥
	@SuppressWarnings("deprecation")
	public void initmPopupWindowView() {
		// // »ñÈ¡×Ô¶¨Òå²¼¾ÖÎÄ¼þpop.xmlµÄÊÓÍ¼
		View customView = getActivity().getLayoutInflater().inflate(
				R.layout.popview_page, null, false);
		groupView = (ListView) customView.findViewById(R.id.lv_group);
		// ´´½¨PopupWindowÊµÀý,200,150·Ö±ðÊÇ¿í¶ÈºÍ¸ß¶È
		popupwindow = new PopupWindow(customView, 150, 270);
		// ÉèÖÃ¶¯»­Ð§¹û [R.style.AnimationFade ÊÇ×Ô¼ºÊÂÏÈ¶¨ÒåºÃµÄ]
		popupwindow.setAnimationStyle(R.style.AnimationFade);
		// ¸½×ÅÔÚÄÄ¸öview£¨Ó¦¸ÃÊÇ¸ù¾ÝÕâ¸öparentÀ´È·¶¨µ¯³öÎ»ÖÃ£©£¬Ïà¶ÔÓÚparentµÄxÖáÆ«ÒÆ £¬Ïà¶ÔÓÚparentµÄyÖáÆ«ÒÆ
		popupwindow.showAsDropDown(customView, 150, 100);

		// Ê¹Æä¾Û¼¯
		popupwindow.setFocusable(true);
		// ÉèÖÃÔÊÐíÔÚÍâµã»÷ÏûÊ§
		popupwindow.setOutsideTouchable(true);
		// Ë¢ÐÂ×´Ì¬£¨±ØÐëË¢ÐÂ·ñÔòÎÞÐ§£©
		popupwindow.update();

		// Õâ¸öÊÇÎªÁËµã»÷¡°·µ»ØBack¡±Ò²ÄÜÊ¹ÆäÏûÊ§£¬²¢ÇÒ²¢²»»áÓ°ÏìÄãµÄ±³¾°£¨ºÜÉñÆæµÄ£©
		popupwindow.setBackgroundDrawable(new BitmapDrawable());

		// ×Ô¶¨ÒåviewÌí¼Ó´¥ÃþÊÂ¼þ
		customView.setOnTouchListener(new OnTouchListener() {

			@SuppressLint("ClickableViewAccessibility")
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (popupwindow != null && popupwindow.isShowing()) {
					popupwindow.dismiss();
					popupwindow = null;
				}
				return false;
			}
		});
		groupView.setDividerHeight(1);
		// Èº×é¹ÜÀí°´Å¥
		group_manage = (Button) customView.findViewById(R.id.group_manage);
		group_manage.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				popupwindow.dismiss();
				Intent intent = new Intent();
				intent.setClass(getActivity(), GroupManageActivity.class);