web-dev-qa-db-fra.com

Comment choisir un numéro de téléphone avec la boîte de dialogue Contacts d'Android

J'utilise l'ancienne API Contacts pour choisir un contact avec un numéro de téléphone. Je souhaite utiliser la nouvelle API ContactsContracts. Je voudrais...

  1. ... une boîte de dialogue affichée avec tous les contacts ayant des numéros de téléphone.
  2. ... à l'utilisateur de choisir un contact ET un de ses numéros de téléphone.
  3. ... accès au numéro de téléphone choisi.

Le ContactsContracts est très compliqué. J'ai trouvé de nombreux exemples, mais aucun ne correspondait à mes besoins. Je ne veux pas choisir un contact et ensuite demander les détails du contact car cela me donnera une liste de leurs numéros de téléphone. J'ai besoin de l'utilisateur pour choisir l'un des numéros de téléphone du contact. Je ne veux pas avoir à écrire mes propres boîtes de dialogue pour afficher les contacts ou que l'utilisateur choisisse un numéro de téléphone. Existe-t-il un moyen simple d'obtenir ce que je veux?

Voici l'ancien code API que j'utilise:

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
  }
}      
23
NateS
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT); 

Ce code pourrait vous aider. Je pense que l'action PICK ne renvoie que l'ID du contact sélectionné. À partir de là, vous pouvez interroger le fournisseur de contacts et s’il existe plusieurs numéros de téléphone, inviter l’utilisateur à en sélectionner un. 

Vous pouvez aussi utiliser ceci (mis à jour):

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

}

Mis à jour le 28/12 -2011

Vous pouvez utiliser ceci:

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

Vous devez adapter cela pour fonctionner avec votre application.

36
Rizvan

Vous trouverez ici un excellent code sur: 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...
        }
    }
}
12
Elad Blau

Parmi les réponses plus anciennes et mes propres tests, j'ai fini par utiliser ceci:

liste de contacts de lancement:

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);

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

Alors, quelles sont les différences avec la réponse de Rizvan?

Sur mon appareil de test (Samsung S3):

  • l'application n'a pas PAS besoin de la permission READ_CONTACS (parce que j'utilise la valeur retournée uri telle quelle, lorsque je n'utilise que son "id" et que je crée un type de requête select =?, l'autorisation se produit)
  • lorsque le contact a plusieurs numéros de téléphone, le sélecteur affiche lui-même une boîte de dialogue pour n'en sélectionner qu'un, puis renvoie uri qui mène directement à ce numéro sélectionné
  • même si certains téléphones renvoient uri en plusieurs numéros, le gestionnaire onActivityResult proposé peut être étendu pour les lire tous et vous pouvez créer votre propre dialogue de sélection.

Cela me semble donc parfaitement adapté à la question posée par OP.

Maintenant je me demande juste:

  1. sur quels téléphones cela nécessitera l’autorisation READ_CONTACTS (cela ne devrait pas, selon http://developer.Android.com/guide/topics/providers/content-provider-basics.html#Intents )
  2. sur quels téléphones il retournera plusieurs numéros au lieu de faire le dialogue de sélection

Faites-moi savoir si vous avez une expérience du monde réel avec elle, merci.

Mise à jour: HTC Desire S, une ROM personnalisée avec Android 4.0.3 -> a les deux problèmes, nécessite l’autorisation READ_CONTACTS pour fonctionner et renvoie plusieurs numéros sans boîte de dialogue de sélection supplémentaire.

10
Ped7g

Je trouve un moyen de choisir exactement le numéro de téléphone de la liste de contacts . Ci-dessous l'extrait de code.

1.Lancez les contacts pour sélectionner des numéros de téléphone en fragments.

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.Choisissez les numéros de téléphone sélectionnés en fragments.

@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();
                }
            }
    }
}

P.S. private final int PICK_CONTACT = 666;

0
chancyWu