你的位置:首页 > 操作系统

[操作系统]通讯录好友笔记


百度通讯录一大把的例子,不过在项目的实际中漏洞还是挺多的,因为现在的通讯录太强大了,特殊字符也能输入,而且我还有同事的通讯录里竟然有用表情来做联系人名字的,这下百度的例子就测底蒙了,所以还是得自己动手,优化了一下,分享的同时也记录下自己的劳动成果,几年后也可以回头看看自己走过的码路

 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(telEntity101                       .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           @Override134           public void onFailure(String message) {135             // TODO Auto-generated method stub136             closeDialog();137             Log.e(TAG, "checkTelBook " + message);138           }139 140           @Override141           public void onError(Exception e) {142             // TODO Auto-generated method stub143             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         // 得到联系人ID186         // Long contactid = phoneCursor.getLong(2);187 188         // 得到联系人头像ID189         // Long photoid = phoneCursor.getLong(3);190 191         // 得到联系人头像Bitamp192         // 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.Contacts199         // .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         // else206         // 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 cList231   */232   @SuppressWarnings("unchecked")233   private void SortContactList(List<DoctorContacts> cList) {234     for (DoctorContacts contact : cList) {235       // 表示没有自定义236 237       if (contact.getFirstGrapheme() == null238           || contact.getFirstGrapheme().equals("")) {239         contact.setFirstGrapheme(getSpells(contact.getName()));240       }241       // 把所有数字转换为#分组242       if (contact.getFirstGrapheme() != null243           && !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 characters285    *      字符串286    * @return 首字母287   */288   private String getSpells(String characters) {289     char c = characters.toCharArray()[0];290     String result = null;291     try {292       // 获取汉字的拼音,如果不是汉字则返回null293       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 block301       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 " + characters311           + "没取到,进入自定义获取 --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/0x43366    * 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 }

View Code

这几个表情是我自己添加的,还有一些手机可以输入聊天表情的,这里就不截图了