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...
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
}
}
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.
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...
}
}
}
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):
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)uri
qui mène directement à ce numéro sélectionné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:
READ_CONTACTS
(cela ne devrait pas, selon http://developer.Android.com/guide/topics/providers/content-provider-basics.html#Intents )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.
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;