2011-12-23 17 views
20

Estoy usando la antigua API de contactos para elegir un contacto con un número de teléfono. Quiero usar la nueva API ContactsContracts. Quiero ...¿Cómo puedo elegir un número de teléfono con el cuadro de diálogo de contactos de Android

  1. ... un cuadro de diálogo que se muestra con todos los contactos que tienen números de teléfono.
  2. ... el usuario para elegir un contacto Y uno de sus números de teléfono.
  3. ... acceso al número de teléfono elegido.

ContactsContracts es muy complicado. Encontré muchos ejemplos, pero ninguno que se ajuste a mis necesidades. No quiero elegir un contacto y luego consultar los detalles del contacto porque esto me dará una lista de sus números de teléfono. Necesito que el usuario elija UNO de los números de teléfono del contacto. No quiero tener que escribir mis propios cuadros de diálogo para mostrar los contactos o hacer que el usuario elija un número de teléfono. ¿Hay alguna manera simple de obtener lo que quiero?

Aquí es el código de la API de edad que estoy usando:

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 
    } 
}  
+0

hay un número suficiente de interrogación en SO para el mismo. – st0le

+1

posible duplicado de [¿Cómo llamar a la lista de contactos de Android?] (Http://stackoverflow.com/questions/866769/how-to-call-android-contacts-list) – st0le

+0

Las otras preguntas eligen un contacto, no lo hacen elige un número de teléfono – NateS

Respuesta

34
Intent intent = new Intent(Intent.ACTION_PICK); 
    intent.setType(ContactsContract.Contacts.CONTENT_TYPE); 
    startActivityForResult(intent, PICK_CONTACT); 


Estos código ayuda U, creo que la actividad de elegir sólo devuelve el ID del contacto elegido. Desde allí puede consultar al proveedor de contactos y si hay números de teléfono múltiples, solicite al usuario que seleccione uno de ellos.


U puede utilizar esto también (actualizado):

 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)); 
        perrsonname.setText(name); 
        Toast.makeText(this, name + " has number " + number, Toast.LENGTH_LONG).show(); 
       } 
      } 
     break; 
     } 

    } 


Hey Actualizado contenido de 28/12: U puede utilizar esto:

@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 
    } 
} 

Debes adaptar esto para que funcione con tu aplicación

+0

¿Está diciendo que no se ha construido de ninguna manera? para elegir un número de teléfono? – NateS

+0

Solo elegir un contacto es agradable, pero necesito elegir uno de los números de teléfono del contacto. El código de la pregunta que usa la API anterior muestra un selector de contactos, cuando se muestra un contacto, si tiene varios números de teléfono, se muestra un pequeño cuadro de diálogo para elegir un número de teléfono (al menos en mi HTC Thunderbolt). Esto es lo que me gustaría hacer, pero con la nueva API. No sé si esta funcionalidad está incorporada o si se necesita un cuadro de diálogo personalizado para elegir un número de teléfono. – NateS

+1

http://developer.android.com/resources/samples/BusinessCard/src/com/example/android/businesscard/index.html Utilice este enlace para Contactos n seleccione incluso para el número ni tratando de hacer código para ello. Sinceramente – Rizvan

10

partir de las respuestas de más edad y mis propias pruebas que terminó usando la siguiente:

lista de contactos de lanzamiento:

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 controlador:

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 
} 

¿Cuáles son las diferencias con la respuesta de Rizvan?

en el dispositivo de pruebas (Samsung S3):

  • la aplicación hace NO necesidad READ_CONTACS permiso (porque uso el devueltos uri como es, cuando se utiliza sólo el "id" de la misma y crear seleccione ID = tipo de consulta, el accidente permiso sucede)
  • cuando el contacto tiene varios números de teléfono, el selector sí lo hace mostrar diálogo para seleccionar sólo uno de ellos, entonces se vuelve uri que conduce directamente a ese único número seleccionado
  • ev es si algún teléfono devuelve uri a varios números, el controlador onActivityResult propuesto puede extenderse para leerlos todos y usted puede hacer su propio diálogo de selección.

Así que esto me parece perfecto para lo que se le preguntó OP.

Ahora sólo me pregunto:

  1. en el que los teléfonos esto requerirá el permiso READ_CONTACTS (no debería, de acuerdo con http://developer.android.com/guide/topics/providers/content-provider-basics.html#Intents)
  2. en el que los teléfonos se volverá varios números en vez de hacer el diálogo de selección

Avísame si tienes experiencia en el mundo real con ella, gracias.

Actualización: HTC Desire S, Rom personalizado con Android 4.0.3 -> tiene ambos problemas, requiere el permiso READ_CONTACTS para funcionar, y devolverá varios números sin diálogo de selección adicional.

+0

HTC M8 requiere READ_CONTACTS con este código, pero parecen proporcionar el número de teléfono en un intento extra con la clave Intent.EXTRA_PHONE_NUMBER – for3st

+0

Obtengo 'IllegalArgumentException: columna inválida data1' en la línea de consulta – Gavriel

11

Aquí se puede encontrar una gran código de: 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... 
     } 
    } 
} 
Cuestiones relacionadas