阅读联系人是仅来自电子邮件存储的显示联系人

时间:2019-07-29 07:18:06

标签: java android

我想创建功能,从我的联系人中读取所有联系人号码,包括sim 1和2联系人,来自电子邮件存储的联系人以及来自电话存储的联系人。但是,在我的应用中,仅显示来自电子邮件存储的联系人。有人请帮助我。非常感谢。

公共类ContactUtils {

//get contacts from phonebook
public static List<PhoneContact> getRawContacts(Context context) {
    List<PhoneContact> contactsList = new ArrayList<>();

    Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
    String[] projection = new String[]{
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
    };

    String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
    String[] selectionArgs = null;
    String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";

    // Build adapter with contact entries
    Cursor mCursor = null;
    Cursor phoneNumCursor = null;

    try {
        mCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);

        while (mCursor.moveToNext()) {
            //get contact name
            String name = mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));

            //get contact name
            String contactID = mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
            //create new phoneContact object
            PhoneContact contact = new PhoneContact();
            contact.setId(Integer.parseInt(contactID));
            contact.setName(name);


            //get all phone numbers in this contact if it has multiple numbers
            phoneNumCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?", new String[]{contactID}, null);

            phoneNumCursor.moveToFirst();


            //create empty list to fill it with phone numbers for this contact
            List<String> phoneNumberList = new ArrayList<>();


            while (!phoneNumCursor.isAfterLast()) {
                //get phone number
                String number = phoneNumCursor.getString(phoneNumCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));


                //prevent duplicates numbers
                if (!phoneNumberList.contains(number))
                    phoneNumberList.add(number);

                phoneNumCursor.moveToNext();
            }

            //fill contact object with phone numbers
            contact.setPhoneNumbers(phoneNumberList);
            //add final phoneContact object to contactList
            contactsList.add(contact);

        }

        mCursor.close();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (mCursor != null)
            mCursor.close();
        if (phoneNumCursor != null)
            phoneNumCursor.close();
    }

    return contactsList;

}


//format number to international number
//if number is not with international code (+1 for example) we will add it
//depending on user country ,so if the user number is +1 1234-111-11
//we will add +1 in this case for all the numbers
//and if it's contains "-" we will remove them
private static String formatNumber(Context context, String countryCode, String number) {

    PhoneNumberUtil util = PhoneNumberUtil.createInstance(context);
    Phonenumber.PhoneNumber phoneNumber;
    String phone = number;
    try {
        //format number depending on user's country code
        phoneNumber = util.parse(number, countryCode);
        phone = util.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);

    } catch (NumberParseException e) {
        e.printStackTrace();
    }

    //remove empty spaces and dashes
    if (phone != null)
        phone = phone.replaceAll(" ", "")
                .replaceAll("-", "")
                .replaceAll("\\(","")
                .replaceAll("\\)","");

    return phone;


}

//get the Contact name from phonebook by number
public static String queryForNameByNumber(Context context, String phone) {
    String name = phone;

    try {
        Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));

        String[] projection = new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME};

        Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null, null);

        if (cursor != null) {
            if (cursor.moveToFirst()) {
                name = cursor.getString(0);
            }
            cursor.close();
        }
    } catch (Exception e) {
        return name;
    }
    return name;

}

我将显示我的联系人列表中的所有联系人,而不仅仅是电子邮件存储中的

2 个答案:

答案 0 :(得分:0)

  ContentResolver cr = context.getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
            null, null, null, null);
    if (cur.getCount() > 0) {
        while (cur.moveToNext()) {
            String id = cur.getString(
                    cur.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cur.getString(
                    cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            String phone="";
            if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                //Query phone here.  Covered next
                Cursor pCur = cr.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
                        new String[]{id}, null);
                while (pCur.moveToNext()) {
                    // Do something with phones
                    phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                }
                pCur.close();
            }

答案 1 :(得分:0)

好吧,您的代码中有一些问题,但是没有一个可以解释您的主要抱怨,您应该在设备上获得所有联系人的所有电话,包括保存在SIM卡上的所有电话。

您的SIM卡上是否保存有未被此代码识别的联系人? 您可以在SIM卡上添加带有特殊电话号码(例如1111111)的新联系人,并添加日志以防您的代码在循环中进入该电话吗?

为了改善您的代码并解决其他一些问题,我将进行一些更改:

  1. 作为从联系人ID到PhoneContact对象的映射,从ArrayList<PhoneContact>更改为HashMap<Long, PhoneContact>
  2. 删除您的selection / selectionArgs / sortOrder变量,无论如何您都不会使用它们
  3. 删除//get all phone numbers in this contact if it has multiple numbers下的第二个光标代码,而是检查HashMap以查看CONTACT_ID是否已添加到地图中,如果已添加,则将新数据添加到同一PhoneContact对象中。如果联系人具有多个电话,那么您现有的代码将为同一个联系人创建许多PhoneContact副本。
  4. 为循环的每一行添加ACCOUNT_TYPE和ACCOUNT_NAME的日志,这样您就可以在日志中看到数据的来源(Gmail,本地存储,SIM等)
  5. 删除您的try / catch,如果您的主循环中发生崩溃,则希望它使应用程序崩溃,这样您就可以理解并解决该问题;如果您遇到崩溃,则可能会解释为什么您没有查看所有数据

您可以在我的答案中看到类似的代码:https://stackoverflow.com/a/57131613/819355