Получить контактную информацию от сборщика контактов Android

Я пытаюсь вызвать сборщик контактов, записать имена людей, телефон и адрес электронной почты в строки и отправить их на другой вид деятельности с помощью намерения. Пока это работает:

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);  
startActivityForResult(intent, 1);  

// ...

@Override  
public void onActivityResult(int reqCode, int resultCode, Intent data) {  
    super.onActivityResult(reqCode, resultCode, data);  
    if (resultCode == Activity.RESULT_OK) {  
        Uri contactData = data.getData();  
        Cursor c =  managedQuery(contactData, null, null, null, null);  
        if (c.moveToFirst()) {  
            String name = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));  
            Intent intent = new Intent(CurrentActivity.this, NewActivity.class);  
            intent.putExtra("name", name);  
            startActivityForResult(intent, 0);  
        }  
    }  
}

Но если я добавлю:

String number = c.getString(c.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER)); 

это сила закрывает

Может быть, есть еще один способ получить их номер?

2 ответа

Решение

Телефонные номера

Телефонные номера хранятся в отдельной таблице и должны запрашиваться отдельно. Для запроса таблицы телефонных номеров используйте URI, хранящийся в переменной SDK ContactsContract.CommonDataKinds.Phone.CONTENT_URI. Используйте условие WHERE для получения телефонных номеров для указанного контакта.

    if (Integer.parseInt(cur.getString(
           cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
        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
        } 
        pCur.close();
    }

Выполните второй запрос к базе данных SQLite контактов Android. Телефонные номера сопоставляются с URI, хранящимся в ContactsContract.CommonDataKinds.Phone.CONTENT_URI. Идентификатор контакта хранится в таблице телефона как ContactsContract.CommonDataKinds.Phone.CONTACT_ID, а предложение WHERE используется для ограничения возвращаемых данных.

Адрес электронной почты

Запрос адресов электронной почты аналогичен телефонным номерам. Запрос должен быть выполнен, чтобы получить адреса электронной почты из базы данных. Запросите URI, хранящийся в ContactsContract.CommonDataKinds.Email.CONTENT_URI, чтобы запросить таблицу адресов электронной почты.

Cursor emailCur = cr.query( 
        ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
        null,
        ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", 
        new String[]{id}, null); 
    while (emailCur.moveToNext()) { 
        // This would allow you get several email addresses
            // if the email addresses were stored in an array
        String email = emailCur.getString(
                      emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
        String emailType = emailCur.getString(
                      emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE)); 
    } 
    emailCur.close();

Как и в случае телефонного запроса, имена полей для таблицы электронной почты также сохраняются в ContactsContract.CommonDataKinds. Запрос по электронной почте выполняется для URI в ContactsContract.CommonDataKinds.Email.CONTENT_URI, и предложение WHERE должно соответствовать полю ContactsContract.CommonDataKinds.Email.CONTACT_ID. Поскольку несколько адресов электронной почты могут быть сохранены в цикле по записям, возвращаемым в курсоре.

Больше уроков здесь

Этот метод требует Android API версии 5 или выше.

Основываясь на принятом ответе, если вы хотите перейти прямо к нужному адресу электронной почты и не требовать разрешения контактов, используйте что-то вроде этого:

private static final int REQUEST_CODE_EMAIL = 1;

void startSelectingEmail() {
    Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
    startActivityForResult(intent, REQUEST_CODE_EMAIL);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_EMAIL) {
        Uri emailUri = data.getData();
        Cursor emailCursor = getContext().getContentResolver().query(emailUri, null, null, null, null);
        if (emailCursor != null) {
            if (emailCursor.moveToFirst()) {
                String email = emailCursor.getString(
                        emailCursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Email.DATA));
                String emailType = emailCursor.getString(
                        emailCursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Email.TYPE));
                Log.d(TAG, "Email: " + emailType + " " + email);
            }
            emailCursor.close();
        }
    }
}

Это не требует разрешения контактов, чтобы прочитать адрес электронной почты, как методы двойного запроса выше. Это также позволяет избежать написания пользовательского интерфейса для выбора пользователем нужного адреса электронной почты для контактов с несколькими адресами электронной почты. Пользователь выбирает конкретный адрес электронной почты в приложении "Контакты", чтобы получить только один результат.

Курсор возвращается с несколькими столбцами в дополнение к просто адресу электронной почты, например отображаемому имени, хотя это было проверено только на Nexus 5 под управлением Android M.

Другие вопросы по тегам