web-dev-qa-db-ja.com

Androidの連絡先ダイアログで電話番号を選択するにはどうすればよいですか

古い連絡先APIを使用して、電話番号の連絡先を選択しています。新しいContactsContracts APIを使用したい。が欲しいです...

  1. ...電話番号を持つすべての連絡先が表示されたダイアログ。
  2. ...連絡先と電話番号のいずれかを選択するユーザー。
  3. ...選択した電話番号へのアクセス。

ContactsContractsは非常に複雑です。多くの例を見つけましたが、自分のニーズに合うものはありませんでした。連絡先を選択し、連絡先の詳細を照会したくないのは、電話番号のリストが表示されるためです。ユーザーに連絡先の電話番号を1つ選択してもらいます。連絡先を表示したり、ユーザーに電話番号を選択させたりするために、独自のダイアログを作成する必要はありません。私が欲しいものを手に入れる簡単な方法はありますか?

これが私が使っている古いAPIコードです:

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

このコードはあなたを助けるかもしれません。 PICKアクションは、選択した連絡先のIDのみを返すと思います。それから、連絡先プロバイダーを照会し、複数の電話番号がある場合、ユーザーにそれらの1つを選択するように要求できます。

これも使用できます(更新済み):

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

}

2011年12月28日更新

あなたはこれを使うことができます:

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

アプリで動作するようにこれを適応させる必要があります。

37
Rizvan

ここからあなたは素晴らしいコードを見つけることができます: 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

以前の回答と私自身のテストから、私はこれを使用して終了しました:

連絡先リストを起動しています:

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ハンドラ:

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
}

それでは、Rizvanの回答との違いは何ですか?

私のテストデバイス(Samsung S3):

  • アプリは[〜#〜]しない[〜#〜]READ_CONTACS権限が必要です(返されたuriをそのまま使用するため、 「id」のみを使用して、select ID =?クエリタイプを作成すると、権限のクラッシュが発生します)
  • 連絡先に複数の電話番号がある場合、ピッカー自体がそのうちの1つだけを選択するダイアログを表示し、選択した単一の番号に直接つながるuriを返します
  • 一部の電話がuriを複数の数値に返す場合でも、提案されたonActivityResultハンドラーを拡張してそれらをすべて読み取り、独自の選択ダイアログを実行できます。

したがって、これはOPが要求したものに完全に適合しているように見えます。

今私はただ疑問に思います:

  1. どの電話では、これにはREAD_CONTACTS権限が必要です(そうする必要はありません http://developer.Android.com/guide/topics/providers/content-provider-basics.html#Intents)によると
  2. どの電話で選択ダイアログを実行する代わりに複数の番号を返します

実世界での経験があれば教えてください、ありがとう。

更新:HTC Desire S、Android 4.0.3->のカスタムromには両方の問題があり、機能するにはREAD_CONTACTS権限が必要です。追加の選択ダイアログなしで複数の数値を返します。

10
Ped7g

連絡先リストから電話番号を正確に選択する1つの方法を見つけます。以下はスニペットです。

1.連絡先を起動して、断片的に電話番号を選択します。

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.選択した電話番号を断片的に選択します。

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

追伸private final int PICK_CONTACT = 666;

0
chancyWu