Как выбрать номер телефона в диалоге контактов Android - PullRequest
23 голосов
/ 23 декабря 2011

Я использую старый API Контактов, чтобы выбрать контакт с номером телефона.Я хочу использовать более новый API ContactsContracts.Я хочу ...

  1. ... диалоговое окно со всеми контактами, которые имеют номера телефонов.
  2. ... пользователю, чтобы выбрать контакт И один из своих телефонных номеров.
  3. ... доступ к выбранному номеру телефона.

ContactsContracts очень сложен.Я нашел много примеров, но ни один из них не соответствует моим потребностям.Я не хочу выбирать контакт, а затем запрашивать его данные, потому что это даст мне список их телефонных номеров.Мне нужно, чтобы пользователь выбрал ОДИН из телефонных номеров контакта.Я не хочу писать свои собственные диалоги для отображения контактов или чтобы пользователь выбирал номер телефона.Есть ли простой способ получить то, что я хочу?

Вот старый код API, который я использую:

static public final int CONTACT = 0;
...
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.Phones.CONTENT_URI);
startActivityForResult(intent, CONTACT);
...
public void onActivityResult (int requestCode, int resultCode, Intent intent) {
  if (resultCode != Activity.RESULT_OK || requestCode != CONTACT) return;
  Cursor c = managedQuery(intent.getData(), null, null, null, null);
  if (c.moveToFirst()) {
     String phone = c.getString(c.getColumnIndexOrThrow(Contacts.Phones.NUMBER));
     // yay
  }
}      

Ответы [ 4 ]

36 голосов
/ 23 декабря 2011
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT); 

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

Вы тоже можете использовать это (обновлено):

public void readcontact(){
    try {
        Intent intent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts/people"));
        startActivityForResult(intent, PICK_CONTACT);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void onActivityResult(int reqCode, int resultCode, Intent data) {
      super.onActivityResult(reqCode, resultCode, data);

      switch (reqCode) {
        case (PICK_CONTACT) :
          if (resultCode == Activity.RESULT_OK) {
              Uri contactData = data.getData();
                Cursor c =  managedQuery(contactData, null, null, null, null);
                startManagingCursor(c);
                if (c.moveToFirst()) {
                    String name = c.getString(c.getColumnIndexOrThrow(People.NAME));    
                    String number = c.getString(c.getColumnIndexOrThrow(People.NUMBER));
                    personname.setText(name);
                    Toast.makeText(this,  name + " has number " + number, Toast.LENGTH_LONG).show();
                 }
           }
         break;
      }

}

Обновлено 28/12-2011

Вы можете использовать это:

@Override  
protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (resultCode == RESULT_OK) {  
        switch (requestCode) {  
        case CONTACT_PICKER_RESULT:
            final EditText phoneInput = (EditText) findViewById(R.id.phoneNumberInput);
            Cursor cursor = null;  
            String phoneNumber = "";
            List<String> allNumbers = new ArrayList<String>();
            int phoneIdx = 0;
            try {  
                Uri result = data.getData();  
                String id = result.getLastPathSegment();  
                cursor = getContentResolver().query(Phone.CONTENT_URI, null, Phone.CONTACT_ID + "=?", new String[] { id }, null);  
                phoneIdx = cursor.getColumnIndex(Phone.DATA);
                if (cursor.moveToFirst()) {
                    while (cursor.isAfterLast() == false) {
                        phoneNumber = cursor.getString(phoneIdx);
                        allNumbers.add(phoneNumber);
                        cursor.moveToNext();
                    }
                } else {
                    //no results actions
                }  
            } catch (Exception e) {  
               //error actions
            } finally {  
                if (cursor != null) {  
                    cursor.close();
                }

                final CharSequence[] items = allNumbers.toArray(new String[allNumbers.size()]);
                AlertDialog.Builder builder = new AlertDialog.Builder(your_class.this);
                builder.setTitle("Choose a number");
                builder.setItems(items, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int item) {
                        String selectedNumber = items[item].toString();
                        selectedNumber = selectedNumber.replace("-", "");
                        phoneInput.setText(selectedNumber);
                    }
                });
                AlertDialog alert = builder.create();
                if(allNumbers.size() > 1) {
                    alert.show();
                } else {
                    String selectedNumber = phoneNumber.toString();
                    selectedNumber = selectedNumber.replace("-", "");
                    phoneInput.setText(selectedNumber);
                }

                if (phoneNumber.length() == 0) {  
                    //no numbers found actions  
                }  
            }  
            break;  
        }  
    } else {
       //activity result error actions
    }  
}

Вам необходимо настроить это для работы с вашим приложением.

12 голосов
/ 25 декабря 2014

Здесь вы можете найти отличный код: http://developer.android.com/training/basics/intents/result.html

static final int PICK_CONTACT_REQUEST = 1;  // The request code
...
private void pickContact() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
    pickContactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request it is that we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            // Get the URI that points to the selected contact
            Uri contactUri = data.getData();
            // We only need the NUMBER column, because there will be only one row in the result
            String[] projection = {Phone.NUMBER};

            // Perform the query on the contact to get the NUMBER column
            // We don't need a selection or sort order (there's only one result for the given URI)
            // CAUTION: The query() method should be called from a separate thread to avoid blocking
            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
            // Consider using CursorLoader to perform the query.
            Cursor cursor = getContentResolver()
                    .query(contactUri, projection, null, null, null);
            cursor.moveToFirst();

            // Retrieve the phone number from the NUMBER column
            int column = cursor.getColumnIndex(Phone.NUMBER);
            String number = cursor.getString(column);

            // Do something with the phone number...
        }
    }
}
10 голосов
/ 24 ноября 2014

Из предыдущих ответов и моих собственных тестов я закончил, используя это:

запуск списка контактов:

import android.content.Intent;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;

...

public static final int PICK_CONTACT = 100;

...

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
intent.setType(Phone.CONTENT_TYPE);  //should filter only contacts with phone numbers
startActivityForResult(intent, PICK_CONTACT);

Обработчик onActivityResult:

private static final String[] phoneProjection = new String[] { Phone.DATA };

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (PICK_CONTACT != requestCode || RESULT_OK != resultCode) return;
    Uri contactUri = data.getData();
    if (null == contactUri) return;
    //no tampering with Uri makes this to work without READ_CONTACTS permission
    Cursor cursor = getContentResolver().query(contactUri, phoneProjection, null, null, null);
    if (null == cursor) return;
    try {
        while (cursor.moveToNext()) {
            String number = cursor.getString(0);
            // ... use "number" as you wish
        }
    } finally {
        cursor.close();
    }
    // "cursor" is closed here already
}

Итак, чем отличаются ответы от Rizvan?

На моем тестовом устройстве (Samsung S3):

  • приложение НЕ нуждается в READ_CONTACS разрешении (потому что я использую возвращенный uri как есть, когда я использую только его "id" и создаю select ID =? Тип запроса,происходит сбой разрешения)
  • когда у контакта есть несколько телефонных номеров, сборщик сам показывает диалоговое окно для выбора только одного из них, а затем возвращает uri, что приводит непосредственно к этому единственному выбранному номеру
  • даже если какой-нибудь телефон вернет uri на несколько номеров, предложенный обработчик onActivityResult можно расширить, чтобы прочитать их все, и вы можете сделать свой собственный диалог выбора.

Так что мне это кажется идеальнымподходит для того, что спросил ОП.

Теперь мне просто интересно:

  1. на каких телефонах для этого потребуется разрешение READ_CONTACTS (не должно, согласно http://developer.android.com/guide/topics/providers/content-provider-basics.html#Intents)
  2. на каких телефонах он будет возвращать несколько номеров вместо того, чтобы делатьдиалог выбора

Дайте мне знать, если у вас есть реальный опыт работы с ним, спасибо.

Обновление: HTC Desire S, пользовательский диск с Android 4.0.3 -> имеет обе проблемы, требует разрешения READ_CONTACTS для работы и возвратит несколько чисел без дополнительного диалога выбора.

0 голосов
/ 26 апреля 2018

Я нахожу один способ точно выбрать номер телефона из списка контактов.Ниже приведен фрагмент кода.

1. Запустите контакты для выбора телефонных номеров во фрагменте.

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);        
// filter the contacts with phone number only
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); 
startActivityForResult(intent, PICK_CONTACT);

2. Выберите выбранные номера телефонов во фрагменте.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case (PICK_CONTACT):
            if (resultCode == Activity.RESULT_OK) {
                Uri contactData = data.getData();
                Cursor cur =  getActivity().getContentResolver().query(contactData, null, null, null, null);
                if (cur == null) return;
                try {
                    if (cur.moveToFirst()) {
                        int phoneIndex = cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                        mobileNoEditText.setText(cur.getString(phoneIndex));
                    }
                }
                finally {
                    cur.close();
                }
            }
    }
}

PS private final int PICK_CONTACT = 666;

...