// just for debug
 public void showContactsInfo() {
   int contactsCount = ContactsHelper.getInstance().getBaseContacts().size();
   for (int i = 0; i < contactsCount; i++) {
     Contacts currentCoutacts = null;
     for (currentCoutacts = ContactsHelper.getInstance().getBaseContacts().get(i);
         null != currentCoutacts;
         currentCoutacts = currentCoutacts.getNextContacts()) {
       Log.i(TAG, "======================================================================");
       String name = currentCoutacts.getName();
       List<PinyinUnit> pinyinUnit = currentCoutacts.getNamePinyinUnits();
       Log.i(
           TAG,
           "++++++++++++++++++++++++++++++:name=["
               + name
               + "] phoneNumber"
               + currentCoutacts.getPhoneNumber()
               + currentCoutacts.isHideMultipleContacts()
               + "firstCharacter=["
               + PinyinUtil.getFirstCharacter(pinyinUnit)
               + "]"
               + "firstLetter=["
               + PinyinUtil.getFirstLetter(pinyinUnit)
               + "]"
               + "+++++++++++++++++++++++++++++");
       int pinyinUnitCount = pinyinUnit.size();
       for (int j = 0; j < pinyinUnitCount; j++) {
         PinyinUnit pyUnit = pinyinUnit.get(j);
         Log.i(
             TAG,
             "j="
                 + j
                 + ",isPinyin["
                 + pyUnit.isPinyin()
                 + "],startPosition=["
                 + pyUnit.getStartPosition()
                 + "]");
         List<PinyinBaseUnit> stringIndex = pyUnit.getPinyinBaseUnitIndex();
         int stringIndexLength = stringIndex.size();
         for (int k = 0; k < stringIndexLength; k++) {
           Log.i(
               TAG,
               "k="
                   + k
                   + "["
                   + stringIndex.get(k).getOriginalString()
                   + "]"
                   + "["
                   + stringIndex.get(k).getPinyin()
                   + "]+["
                   + stringIndex.get(k).getNumber()
                   + "]");
         }
       }
     }
   }
 }
  @SuppressLint("DefaultLocale")
  private List<Contacts> loadContacts(Context context) {
    List<Contacts> kanjiStartContacts = new ArrayList<Contacts>();
    HashMap<String, Contacts> kanjiStartContactsHashMap = new HashMap<String, Contacts>();

    List<Contacts> nonKanjiStartContacts = new ArrayList<Contacts>();
    HashMap<String, Contacts> nonKanjiStartContactsHashMap = new HashMap<String, Contacts>();

    List<Contacts> contacts = new ArrayList<Contacts>();

    Contacts cs = null;
    Cursor cursor = null;
    String sortkey = null;
    long startLoadTime = System.currentTimeMillis();
    String[] projection =
        new String[] {
          ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
          ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
          ContactsContract.CommonDataKinds.Phone.NUMBER
        };
    try {

      cursor =
          context
              .getContentResolver()
              .query(
                  ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                  projection,
                  null,
                  null,
                  "sort_key");

      int idColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
      int dispalyNameColumnIndex =
          cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
      int numberColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
      while (cursor.moveToNext()) {

        String id = cursor.getString(idColumnIndex);
        String displayName = cursor.getString(dispalyNameColumnIndex);
        String phoneNumber = cursor.getString(numberColumnIndex);
        //	Log.i(TAG, "id=["+id+"]name=["+displayName+"]"+"number=["+phoneNumber+"]");

        boolean kanjiStartContactsExist = kanjiStartContactsHashMap.containsKey(id);
        boolean nonKanjiStartContactsExist = nonKanjiStartContactsHashMap.containsKey(id);

        if (true == kanjiStartContactsExist) {
          cs = kanjiStartContactsHashMap.get(id);
          Contacts.addMultipleContact(cs, phoneNumber);
        } else if (true == nonKanjiStartContactsExist) {
          cs = nonKanjiStartContactsHashMap.get(id);
          Contacts.addMultipleContact(cs, phoneNumber);
        } else {

          cs = new Contacts(id, displayName, phoneNumber);
          PinyinUtil.chineseStringToPinyinUnit(cs.getName(), cs.getNamePinyinUnits());
          sortkey = PinyinUtil.getSortKey(cs.getNamePinyinUnits()).toUpperCase();
          cs.setSortKey(praseSortKey(sortkey));
          boolean isKanji = PinyinUtil.isKanji(cs.getName().charAt(0));

          if (true == isKanji) {
            kanjiStartContactsHashMap.put(id, cs);
          } else {
            nonKanjiStartContactsHashMap.put(id, cs);
          }
        }
      }
    } catch (Exception e) {

    } finally {
      if (null != cursor) {
        cursor.close();
        cursor = null;
      }
    }

    kanjiStartContacts.addAll(kanjiStartContactsHashMap.values());
    Collections.sort(kanjiStartContacts, Contacts.mAscComparator);

    nonKanjiStartContacts.addAll(nonKanjiStartContactsHashMap.values());
    Collections.sort(nonKanjiStartContacts, Contacts.mAscComparator);

    // contacts.addAll(nonKanjiStartContacts);
    contacts.addAll(kanjiStartContacts);

    // merge nonKanjiStartContacts and kanjiStartContacts
    int lastIndex = 0;
    boolean shouldBeAdd = false;
    for (int i = 0; i < nonKanjiStartContacts.size(); i++) {
      String nonKanfirstLetter =
          PinyinUtil.getFirstLetter(nonKanjiStartContacts.get(i).getNamePinyinUnits());
      // Log.i(TAG, "nonKanfirstLetter=["+nonKanfirstLetter+"]");
      int j = 0;
      for (j = 0 + lastIndex; j < contacts.size(); j++) {
        String firstLetter = PinyinUtil.getFirstLetter(contacts.get(j).getNamePinyinUnits());
        lastIndex++;
        if (firstLetter.charAt(0) > nonKanfirstLetter.charAt(0)) {
          shouldBeAdd = true;
          break;
        } else {
          shouldBeAdd = false;
        }
      }

      if (lastIndex >= contacts.size()) {
        lastIndex++;
        shouldBeAdd = true;
        // Log.i(TAG, "lastIndex="+lastIndex);
      }

      if (true == shouldBeAdd) {
        contacts.add(j, nonKanjiStartContacts.get(i));
        shouldBeAdd = false;
      }
    }

    long endLoadTime = System.currentTimeMillis();
    Log.i(
        TAG,
        "endLoadTime-startLoadTime=["
            + (endLoadTime - startLoadTime)
            + "] contacts.size()="
            + contacts.size());

    /*for (int i = 0; i < contacts.size(); i++) {
    	Log.i(TAG, "****************************************");
    	Contacts currentContacts = contacts.get(i);
    	while (null != currentContacts) {
    		Log.i(TAG, "name[" + currentContacts.getName()+"]phoneNumber[" + currentContacts.getPhoneNumber()+"]");
    		currentContacts = currentContacts.getNextContacts();
    	}
    }*/

    return contacts;
  }