web-dev-qa-db-de.com

Wie kann ich eine Telefonnummer im Kontaktdialog von Android auswählen?

Ich verwende die alte Kontakt-API, um einen Kontakt mit einer Telefonnummer auszuwählen. Ich möchte die neuere ContactsContracts-API verwenden. Ich will...

  1. ... ein Dialog mit allen Kontakten, die Telefonnummern haben.
  2. ... der Benutzer kann einen Kontakt UND eine seiner Telefonnummern auswählen.
  3. ... auf die gewählte Telefonnummer zugreifen.

Der ContactsContracts ist sehr kompliziert. Ich habe viele Beispiele gefunden, aber keine, die meinen Bedürfnissen entsprechen. Ich möchte keinen Kontakt auswählen und dann die Details des Kontakts abfragen, da mir eine Liste der Telefonnummern angezeigt wird. Der Benutzer muss eine der Telefonnummern des Kontakts auswählen. Ich möchte keine eigenen Dialoge schreiben, um die Kontakte anzuzeigen oder den Benutzer eine Telefonnummer auswählen zu lassen. Gibt es einen einfachen Weg, um zu bekommen, was ich will?

Hier ist der alte API-Code, den ich verwende:

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

Dieser Code kann Ihnen helfen. Ich denke, die PICK-Aktion gibt nur die ID des ausgewählten Kontakts zurück. Daraufhin könnten Sie den Kontaktanbieter abfragen. Wenn mehrere Telefonnummern vorhanden sind, fordern Sie den Benutzer auf, eine davon auszuwählen. 

Sie können dies auch verwenden (aktualisiert):

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

}

Aktualisiert am 28/12-2011

Sie können dies verwenden:

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

Sie müssen dies anpassen, um mit Ihrer App zu arbeiten.

36
Rizvan

Hier finden Sie einen großartigen Code von: 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

Aus den älteren Antworten und meinen eigenen Tests beendete ich diese Verwendung:

kontaktliste starten:

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
}

Worin unterscheiden sich die Antworten von Rizvan?

Auf meinem Testgerät (Samsung S3):

  • die App hatNICHTneed READ_CONTACS-Berechtigung (da ich die zurückgegebene uri so wie sie ist, wenn ich nur die "id" davon verwende und den Abfragetyp select ID =?
  • wenn der Kontakt mehrere Telefonnummern hat, zeigt der Picker selbst ein Dialogfeld, in dem nur eine davon ausgewählt wird. Dann wird uri zurückgegeben, die direkt zu dieser ausgewählten Nummer führt
  • selbst wenn ein Telefon uri zu mehreren Nummern zurückgeben würde, kann der vorgeschlagene onActivityResult-Handler erweitert werden, um sie alle zu lesen, und Sie können Ihren eigenen Auswahldialog ausführen.

Das sieht für mich also perfekt aus, was OP verlangt.

Jetzt wundere ich mich nur:

  1. auf welchen Telefonen ist hierfür die READ_CONTACTS-Berechtigung erforderlich (dies sollte laut http://developer.Android.com/guide/topics/providers/content-provider-basics.html#Intents nicht der Fall sein)
  2. bei welchen Telefonen werden mehrere Nummern zurückgegeben, anstatt den Auswahldialog auszuführen

Lassen Sie mich wissen, ob Sie echte Erfahrung damit haben, danke.

Update: HTC Desire S, Benutzerdefinierte ROM mit Android 4.0.3 -> hat beide Probleme, erfordert die Berechtigung READ_CONTACTS, um zu funktionieren, und gibt mehrere Nummern ohne zusätzlichen Auswahldialog zurück.

10
Ped7g

Ich finde eine Möglichkeit, genau die Telefonnummer aus der Kontaktliste zu wählen. Nachfolgend ist der Ausschnitt dargestellt.

1.Starten Sie Kontakte, um Telefonnummern im Fragment auszuwählen.

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. Wählen Sie die ausgewählten Telefonnummern in Fragment aus.

@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