2011-12-23 1 views
20

Sto utilizzando la vecchia API Contatti per scegliere un contatto con un numero di telefono. Voglio utilizzare la nuova API ContactsContracts. Voglio ...Come scegliere un numero di telefono con la finestra di dialogo dei contatti di Android

  1. ... una finestra di dialogo mostrata con tutti i contatti che hanno numeri di telefono.
  2. ... l'utente per scegliere un contatto E uno dei loro numeri di telefono.
  3. ... accesso al numero di telefono scelto.

I contratti di contatto sono molto complicati. Ho trovato molti esempi, ma nessuno che si adatta alle mie esigenze. Non voglio scegliere un contatto e quindi richiedere i dettagli del contatto perché questo mi darà un elenco dei loro numeri di telefono. Ho bisogno che l'utente scelga UNO dei numeri di telefono del contatto. Non voglio dover scrivere le mie finestre di dialogo per visualizzare i contatti o fare in modo che l'utente scelga un numero di telefono. C'è un modo semplice per ottenere quello che voglio?

Ecco il vecchio codice API sto 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

ci sono abbastanza domanda su SO per lo stesso. – st0le

+1

possibile duplicato di [Come chiamare elenco contatti Android?] (Http://stackoverflow.com/questions/866769/how-to-call-android-contacts-list) – st0le

+0

Le altre domande selezionano un contatto, non lo fanno scegli un numero di telefono. – NateS

risposta

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


Questi codice consente u, penso che l'attività PICK restituisce solo l'ID del contatto selezionato. Da ciò è possibile interrogare il fornitore di contatti e se ci sono numeri di telefono multipli , richiedere all'utente di selezionarne uno.


U può usare anche questo (aggiornato):

 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 contenuto aggiornato di 28/12: U può usare questa:

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

Devi adattarlo per funzionare con la tua app

+0

Stai dicendo che non esiste un modo integrato? scegliere un numero di telefono? – NateS

+0

È sufficiente selezionare un contatto, ma è necessario selezionare uno dei numeri di telefono del contatto. Il codice nella domanda che utilizza la vecchia API mostra un selettore di contatti, quando viene mostrato un contatto, se ha più numeri di telefono, viene mostrata una piccola finestra di dialogo per selezionare un numero di telefono (almeno sul mio HTC Thunderbolt). Questo è quello che mi piacerebbe fare ma con la nuova API. Non so se questa funzionalità è integrata o se è necessaria una finestra di dialogo personalizzata per scegliere un numero di telefono. – NateS

+1

http://developer.android.com/resources/samples/BusinessCard/src/com/example/android/businesscard/index.html Utilizzare questo collegamento per la selezione di Contatti n anche per il numero ni che tenta di eseguire il codice per tale scopo. Sperabilmente – Rizvan

10

Dalle risposte anziani e le mie prove ho finito di utilizzare questo:

lista dei contatti di lancio:

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

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 
} 

Quindi quali sono le differenze rispetto a Rizvan?

Sul mio dispositivo di prova (Samsung S3):

  • l'applicazione fa NON necessità READ_CONTACS permesso (perché io uso la tornati uri così com'è, quando uso solo il "id" di esso e creo selezionare ID =? tipo di query, il crollo autorizzazione accade)
  • quando il contatto ha più numeri di telefono, il selettore si fa dialogo mostrare per selezionare solo uno di loro, poi ritorna uri che conduce direttamente a quel singolo numero selezionato
  • ev Se un telefono restituisce uri a più numeri, il gestore onActivityResult proposto può essere esteso per leggerli tutti e si può fare la propria finestra di selezione.

Quindi questo mi sembra perfetto per quello che ha chiesto OP.

Ora mi chiedo:

  1. su cui telefoni questo richiederà il permesso READ_CONTACTS (non dovrebbe, secondo i http://developer.android.com/guide/topics/providers/content-provider-basics.html#Intents)
  2. sui quali telefoni tornerà più numeri invece di fare il dialogo di selezione

Fammi sapere se si dispone di esperienza del mondo reale con esso, grazie.

Aggiornamento: HTC Desire S, rom personalizzata con Android 4.0.3 -> ha entrambi i problemi, richiede il permesso READ_CONTACTS per funzionare e restituirà più numeri senza ulteriore finestra di selezione.

+0

HTC M8 richiede READ_CONTACTS con questo codice, ma sembra che abbia fornito il numero di telefono in un intento extra con la chiave Intent.EXTRA_PHONE_NUMBER – for3st

+0

Ottiene 'IllegalArgumentException: dati colonna1 non validi sulla riga di query – Gavriel

11

Qui è possibile trovare una grande codice da: 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... 
     } 
    } 
}