标签:
百度通讯录一大把的例子,不过在项目的实际中漏洞还是挺多的,因为现在的通讯录太强大了,特殊字符也能输入,而且我还有同事的通讯录里竟然有用表情来做联系人名字的,这下百度的例子就测底蒙了,所以还是得自己动手,优化了一下,分享的同时也记录下自己的劳动成果,几年后也可以回头看看自己走过的码路
1 /** 通讯录 **/ 2 @SuppressLint("DefaultLocale") 3 public class DoctorContactActivity extends BaseActivity { 4 5 private List<DoctorContacts> cList = new ArrayList<DoctorContacts>(); 6 private List<String> telItem = new ArrayList<String>(); 7 private List<ContactsAll> allList = new ArrayList<ContactsAll>(); 8 private final String[] PHONES_PROJECTION = new String[] { 9 Phone.DISPLAY_NAME, Phone.NUMBER, Photo.PHOTO_ID, Phone.CONTACT_ID }; 10 // 存放国标一级汉字不同读音的起始区位码 11 private static final int[] secPosValueList = { 1601, 1637, 1833, 2078, 12 2274, 2302, 2433, 2594, 2787, 3106, 3212, 3472, 3635, 3722, 3730, 13 3858, 4027, 4086, 4390, 4558, 4684, 4925, 5249, 5600 }; 14 // 存放国标一级汉字不同读音的起始区位码对应读音 15 private static final char[] firstLetter = { ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, 16 ‘g‘, ‘h‘, ‘j‘, ‘k‘, ‘l‘, ‘m‘, ‘n‘, ‘o‘, ‘p‘, ‘q‘, ‘r‘, ‘s‘, ‘t‘, 17 ‘w‘, ‘x‘, ‘y‘, ‘z‘ }; 18 private static final int GB_SP_DIFF = 160; 19 private Context context; 20 private PinnedSectionListView listView; 21 private ContactsSidebar sidebar; 22 private DoctorContactsAdapter adapter = null; 23 private String TAG = "DoctorContactActivity"; 24 private static HanyuPinyinOutputFormat spellFormat = new HanyuPinyinOutputFormat(); 25 26 @SuppressLint("DefaultLocale") 27 @Override 28 protected void onCreate(Bundle savedInstanceState) { 29 // TODO Auto-generated method stub 30 super.onCreate(savedInstanceState); 31 context = DoctorContactActivity.this; 32 setContentView(R.layout.activity_friends_message_contact); 33 listView = (PinnedSectionListView) findViewById(R.id.friends_message_contact_listview); 34 sidebar = (ContactsSidebar) findViewById(R.id.sidebar); 35 allList.clear(); 36 cList.clear(); 37 // UPPERCASE:大写 (ZHONG) 38 // LOWERCASE:小写 (zhong) 39 spellFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE); 40 // WITHOUT_TONE:无音标 (zhong) 41 // WITH_TONE_NUMBER:1-4数字表示英标 (zhong4) 42 // WITH_TONE_MARK:直接用音标符(必须WITH_U_UNICODE否则异常) (zhòng) 43 spellFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); 44 // WITH_V:用v表示ü (nv) 45 // WITH_U_AND_COLON:用"u:"表示ü (nu:) 46 // WITH_U_UNICODE:直接用ü (nü) 47 spellFormat.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE); 48 // new Thread(new Runnable() { 49 // public void run() { 50 getPhoneContacts(); 51 // } 52 // }).start(); 53 54 // for(int i = 0;i<5;i++){ 55 // DoctorContacts c = new DoctorContacts(); 56 // c.setFirstGrapheme("-1");//自定义分组 57 // c.setMobileNo("测试"); 58 // c.setName("测试"); 59 // cList.add(c); 60 // } 61 checkTelBook(); 62 adapter = new DoctorContactsAdapter(context, allList); 63 listView.setAdapter(adapter); 64 sidebar.setListView(listView); 65 } 66 67 private void checkTelBook() { 68 telItem.clear(); 69 for (DoctorContacts c : cList) { 70 if (c.getMobileNo() != null) { 71 telItem.add(c.getMobileNo()); 72 } 73 } 74 if (telItem.size() == 0) { 75 Toast.makeText(context, "您的通讯录中没有联系人", 0).show(); 76 return; 77 } 78 String telList = new Gson().toJson(telItem); 79 String umerId = UMDocApplication.getInstance().getPerson().getUmerId(); 80 String easemobName = UMDocApplication.getInstance().getPerson() 81 .getEasemobName(); 82 showDialog("正在加载中..."); 83 ApiClient.checkTelBook(umerId, easemobName, telList, 84 new ApiClient.ClientCallback() { 85 86 @Override 87 public void onSuccess(Object data) { 88 // TODO Auto-generated method stub 89 TelsEntity rEntity = (TelsEntity) data; 90 if (rEntity.reqResult.equals("success")) { 91 if (rEntity.data != null) { 92 List<TelEntity> list = rEntity.data; 93 for (TelEntity telEntity : list) { 94 DoctorContacts contacts = new DoctorContacts(); 95 contacts.setFirstGrapheme("-1"); 96 contacts.setMobileNo(telEntity.getTel()); 97 contacts.setStatus(telEntity.getStatus()); 98 contacts.setUserId(telEntity 99 .getEasemobName()); 100 String tel = getContactsName(telEntity 101 .getTel()); 102 if (tel != null) { 103 contacts.setName(tel); 104 } 105 106 cList.add(contacts); 107 } 108 SortContactList(cList); 109 String grapheme = null; 110 for (DoctorContacts c : cList) { 111 if (!c.getFirstGrapheme().equals(grapheme)) { 112 ContactsAll contacts = new ContactsAll(); 113 contacts.setMsg(c.getFirstGrapheme() 114 .toUpperCase()); 115 contacts.setTypeMsg(0); 116 contacts.setTypeSection(0); 117 allList.add(contacts); 118 grapheme = c.getFirstGrapheme(); 119 } 120 ContactsAll all = new ContactsAll(); 121 all.setTypeMsg(1); 122 all.setTypeSection(1); 123 all.setContent(c); 124 allList.add(all); 125 all = null; 126 } 127 adapter.notifyDataSetChanged(); 128 } 129 } 130 closeDialog(); 131 } 132 133 @Override 134 public void onFailure(String message) { 135 // TODO Auto-generated method stub 136 closeDialog(); 137 Log.e(TAG, "checkTelBook " + message); 138 } 139 140 @Override 141 public void onError(Exception e) { 142 // TODO Auto-generated method stub 143 closeDialog(); 144 Log.e(TAG, "checkTelBook " + e.getMessage()); 145 } 146 }); 147 } 148 149 /** 根据电话号码获取联系人信息并且过滤改联系人 **/ 150 private String getContactsName(String tel) { 151 if (tel == null) { 152 return ""; 153 } 154 String result = null; 155 for (DoctorContacts c : cList) { 156 if (c.getMobileNo() != null && tel.equals(c.getMobileNo())) { 157 result = c.getName(); 158 cList.remove(c); 159 break; 160 } 161 } 162 return result; 163 } 164 165 /** 得到手机通讯录联系人信息 **/ 166 @SuppressLint("NewApi") 167 private void getPhoneContacts() { 168 ContentResolver resolver = context.getContentResolver(); 169 170 // 获取手机联系人 171 Cursor phoneCursor = resolver.query(Phone.CONTENT_URI, 172 PHONES_PROJECTION, null, null, null); 173 174 if (phoneCursor != null) { 175 while (phoneCursor.moveToNext()) { 176 DoctorContacts contacts = new DoctorContacts(); 177 // 得到联系人名称 178 String contactName = phoneCursor.getString(0); 179 if (contactName == null) 180 continue; 181 182 // 得到手机号码 183 String phoneNumber = phoneCursor.getString(1); 184 185 // 得到联系人ID 186 // Long contactid = phoneCursor.getLong(2); 187 188 // 得到联系人头像ID 189 // Long photoid = phoneCursor.getLong(3); 190 191 // 得到联系人头像Bitamp 192 // Bitmap contactPhoto = null; 193 194 // photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的 195 // if (photoid > 0) { 196 // Uri uri = ContentUris.withAppendedId( 197 // ContactsContract.Contacts.CONTENT_URI, contactid); 198 // InputStream input = ContactsContract.Contacts 199 // .openContactPhotoInputStream(resolver, uri); 200 // contactPhoto = BitmapFactory.decodeStream(input); 201 // if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) 202 // input = 203 // ContactsContract.Contacts.openContactPhotoInputStream(resolver, 204 // uri, bigPicture); 205 // else 206 // input = 207 // ContactsContract.Contacts.openContactPhotoInputStream(resolver, 208 // uri); 209 // if (input != null) { 210 // IOUtils.closeQuietly(input); 211 // } else { 212 // contactPhoto = BitmapFactory.decodeResource( 213 // context.getResources(), R.drawable.pic_head_none_login); 214 // } 215 contacts.setMobileNo(phoneNumber); 216 contacts.setName(contactName); 217 if (phoneNumber.startsWith("1")) { 218 cList.add(contacts); 219 } 220 221 } 222 223 phoneCursor.close(); 224 } 225 } 226 227 /** 228 * 对指定的list集合进行字母排序 229 * 230 * @param cList 231 */ 232 @SuppressWarnings("unchecked") 233 private void SortContactList(List<DoctorContacts> cList) { 234 for (DoctorContacts contact : cList) { 235 // 表示没有自定义 236 237 if (contact.getFirstGrapheme() == null 238 || contact.getFirstGrapheme().equals("")) { 239 contact.setFirstGrapheme(getSpells(contact.getName())); 240 } 241 // 把所有数字转换为#分组 242 if (contact.getFirstGrapheme() != null 243 && !contact.getFirstGrapheme().equals("-1") 244 && isInteger(contact.getFirstGrapheme())) { 245 contact.setFirstGrapheme("#"); 246 } 247 248 } 249 @SuppressWarnings("rawtypes") 250 Comparator comp = new Comparator() { 251 public int compare(Object o1, Object o2) { 252 DoctorContacts c1 = (DoctorContacts) o1; 253 DoctorContacts c2 = (DoctorContacts) o2; 254 if (c1.getFirstGrapheme().compareToIgnoreCase( 255 c2.getFirstGrapheme()) < 0) 256 return -1; 257 else if (c1.getFirstGrapheme().equalsIgnoreCase( 258 c2.getFirstGrapheme())) 259 return 0; 260 else if (c1.getFirstGrapheme().compareToIgnoreCase( 261 c2.getFirstGrapheme()) > 0) 262 return 1; 263 return 0; 264 } 265 }; 266 Collections.sort(cList, comp); 267 } 268 269 /** 270 * 判断字符串是否是整数 271 */ 272 public boolean isInteger(String value) { 273 try { 274 Integer.parseInt(value); 275 return true; 276 } catch (NumberFormatException e) { 277 return false; 278 } 279 } 280 281 /** 282 * 获取一个字符串的首字母 283 * 284 * @param characters 285 * 字符串 286 * @return 首字母 287 */ 288 private String getSpells(String characters) { 289 char c = characters.toCharArray()[0]; 290 String result = null; 291 try { 292 // 获取汉字的拼音,如果不是汉字则返回null 293 String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(c, 294 spellFormat); 295 if (pinyin != null) { 296 result = String.valueOf(pinyin[0].toCharArray()[0]) 297 .toLowerCase();// 取拼音的首个字母 298 } 299 } catch (BadHanyuPinyinOutputFormatCombination e) { 300 // TODO Auto-generated catch block 301 Log.e(TAG, "getSpells " + e.getMessage()); 302 e.printStackTrace(); 303 } 304 if (result == null) { // 如果上面没有取到则用自己的方法再取一次 305 306 if (!isNumeric(characters)) {// 如果为特殊字符,比如表情等,自动归类为# 307 Log.d(TAG, "getSpells " + characters + "字符转换为# --isNumeric"); 308 return "#"; 309 } 310 Log.d(TAG, "getSpells " + characters 311 + "没取到,进入自定义获取 --getFirstLetter"); 312 StringBuffer buffer = new StringBuffer(); 313 for (int i = 0; i < characters.length(); i++) { 314 char ch = characters.charAt(i); 315 // 判断是否为汉字,如果左移7为0就不是汉字,否则是汉字 316 if ((ch >> 7) == 0) { 317 buffer.append(characters.substring(0, 1)); 318 break; 319 } else if (String.valueOf(ch) != null) {// 获取汉字的首字母 320 char spell = getFirstLetter(ch); 321 if (String.valueOf(spell) != null) 322 buffer.append(String.valueOf(spell));// 表示获取每个汉字的首字母 323 break;// 以获取到首字母就截至获取下一个 324 } 325 } 326 result = buffer.toString().trim().toLowerCase(); 327 } 328 329 return result; 330 } 331 332 /** 判断是否为数字 **/ 333 public static boolean isNumeric(String str) { 334 for (int i = str.length(); --i >= 0;) { 335 if (!Character.isDigit(str.charAt(i))) { 336 return false; 337 } 338 } 339 return true; 340 } 341 342 /** 获取首字母,因为上面的过滤,所以此方法只会进来数字或特殊字符 **/ 343 private Character getFirstLetter(char ch) { 344 345 byte[] uniCode = null; 346 try { 347 uniCode = String.valueOf(ch).getBytes("GBK"); 348 if (uniCode == null) { 349 return null; 350 } 351 } catch (UnsupportedEncodingException e) { 352 Log.e(TAG, "getFirstLetter " + e.getMessage()); 353 e.printStackTrace(); 354 return null; 355 } 356 if (uniCode[0] < 128 && uniCode[0] > 0) { // 非汉字 357 return null; 358 } 359 char c = convert(uniCode); 360 return c; 361 } 362 363 /** 364 * 获取一个汉字的拼音首字母。 GB码两个字节分别减去160,转换成10进制码组合就可以得到区位码 365 * 例如汉字“你”的GB码是0xC4/0xE3,分别减去0xA0(160)就是0x24/0x43 366 * 0x24转成10进制就是36,0x43是67,那么它的区位码就是3667,在对照表中读音为‘n’ 367 */ 368 private static char convert(byte[] bytes) { 369 char result = ‘-‘;// 初始值 370 int secPosValue = 0; 371 int i; 372 for (i = 0; i < bytes.length; i++) { 373 bytes[i] -= GB_SP_DIFF; 374 } 375 secPosValue = bytes[0] * 100 + bytes[1]; 376 for (i = 0; i < 23; i++) { 377 if (secPosValue >= secPosValueList[i] 378 && secPosValue < secPosValueList[i + 1]) { 379 result = firstLetter[i]; 380 break; 381 } 382 } 383 return result; 384 } 385 386 public void back(View view) { 387 finish(); 388 } 389 }
这几个表情是我自己添加的,还有一些手机可以输入聊天表情的,这里就不截图了
标签:
原文地址:http://www.cnblogs.com/LiuZhen/p/4881039.html