どうもこんにちは。
Android のいいところ Intent 連携。
そんな便利機能で電話帳と連携して、選択した人の電話番号を取得したい。
ただし選択した人の電話番号が一つとは限らない。
Google 先生に聞いてみたら一つだけ取得するサンプルは結構あるんだけど、
そこから全件取得するってのはなかった(と思う)。
なのでこしらえた。
対象は Android 2.x 以上。 ICS も行けるかと思う(実機では試してない)。
- [連絡先]ボタンをクリックしたら、[電話帳]が開く。
- [電話帳]から任意に選択する。
- 選択された人が複数電話番号を持っていたら、ダイアログを表示して選択する。
- 選択した電話番号を表示する。
AndroidManifest.xml には以下のパーミッションの追記を忘れずに。
<uses-permission android:name="android.permission.READ_CONTACTS"/>
レイアウトファイルはどうでもいいけど・・・。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="vertical" > | |
<Button | |
android:id="@+id/button" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:text="連絡先" /> | |
<TextView | |
android:id="@+id/text" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" /> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example; | |
import android.app.Activity; | |
import android.app.AlertDialog; | |
import android.content.ContentResolver; | |
import android.content.DialogInterface; | |
import android.content.Intent; | |
import android.database.Cursor; | |
import android.net.Uri; | |
import android.os.Bundle; | |
import android.provider.ContactsContract; | |
import android.view.View; | |
import android.view.View.OnClickListener; | |
import android.widget.Button; | |
import android.widget.TextView; | |
/** | |
* @author peko | |
* | |
*/ | |
public class MainActivity extends Activity implements DialogInterface.OnClickListener { | |
private static final String TAG = "MainActivity"; | |
private static final int PICK_CONTACT = 1111; | |
private AlertDialog.Builder _alertDialogBuilder; | |
private TextView _phoneNumberTextView; | |
private String[] _phoneNumbers; | |
/* | |
* (non-Javadoc) | |
* | |
* @see android.app.Activity#onCreate(android.os.Bundle) | |
*/ | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
this.setContentView(R.layout.main); | |
this._alertDialogBuilder = new AlertDialog.Builder(this); | |
this._phoneNumberTextView = (TextView) this.findViewById(R.id.text); | |
((Button) this.findViewById(R.id.button)).setOnClickListener(new OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
Intent pickIntent = new Intent(Intent.ACTION_PICK, | |
ContactsContract.Contacts.CONTENT_URI); | |
startActivityForResult(pickIntent, MainActivity.PICK_CONTACT); | |
} | |
}); | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see android.app.Activity#onActivityResult(int, int, | |
* android.content.Intent) | |
*/ | |
@Override | |
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
super.onActivityResult(requestCode, resultCode, data); | |
if (requestCode == MainActivity.PICK_CONTACT) { | |
if (resultCode == Activity.RESULT_OK) { | |
if (null != data) { | |
Uri contactData = data.getData(); | |
String displayName = this._getDisplayName(contactData); | |
this._phoneNumbers = this._getPhoneNumbers(displayName); | |
if (this._phoneNumbers.length > 1) { | |
this._createNumberSelectAlertDialog(displayName, this._phoneNumbers); | |
} else if (this._phoneNumbers.length == 1) { | |
this._phoneNumberTextView.setText(this._phoneNumbers[0]); | |
} | |
} | |
} | |
} | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see | |
* android.content.DialogInterface.OnClickListener#onClick(android.content | |
* .DialogInterface, int) | |
*/ | |
@Override | |
public void onClick(DialogInterface dialog, int which) { | |
String selectedPhoneNumber = this._phoneNumbers[which]; | |
this._phoneNumberTextView.setText(selectedPhoneNumber); | |
} | |
/** | |
* コンタクトリストのURIから表示名を取得する | |
* | |
* @param contactData | |
* @return | |
*/ | |
private String _getDisplayName(Uri contactData) { | |
String displayName = null; | |
if (null != contactData) { | |
ContentResolver contentResolver = this.getContentResolver(); | |
Cursor cursor = contentResolver.query(contactData, null, null, null, null); | |
cursor.moveToFirst(); | |
int columnIndex = cursor | |
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); | |
displayName = cursor.getString(columnIndex); | |
cursor.close(); | |
} | |
return displayName; | |
} | |
/** | |
* コンタクトリストから表示名で検索して、その名前に紐付いている電話番号を取得する | |
* | |
* @param displayName | |
* @return | |
*/ | |
private String[] _getPhoneNumbers(String displayName) { | |
ContentResolver contentResolver = this.getContentResolver(); | |
Cursor cursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, | |
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + "=?", | |
new String[] { displayName }, null); | |
cursor.moveToFirst(); | |
String[] names = new String[cursor.getCount()]; | |
do { | |
int index = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); | |
String number = cursor.getString(index); | |
names[cursor.getPosition()] = number; | |
} while (cursor.moveToNext()); | |
cursor.close(); | |
return names; | |
} | |
/** | |
* 電話番号選択のダイアログを出す | |
* | |
* @param title | |
* @param items | |
*/ | |
private void _createNumberSelectAlertDialog(String title, String[] items) { | |
this._alertDialogBuilder.setTitle(title); | |
this._alertDialogBuilder.setItems(items, this); | |
AlertDialog alert = this._alertDialogBuilder.create(); | |
alert.show(); | |
} | |
} |
表示名を取得して、その表示名をキーにもう一回検索かけてと・・・。
なんか回りくどい。いい方法無いかな・・・。
まあ、なんで ICS も行けると思うって書いたかというと、
ContentResolver#query()
って書いたとこ。
Activity#managedQuery()にしてたんだけど API Level 15 から deprecated になったみたいで、
使わないほうがいいらしい。
ココらへんもググった情報の多くは managedQuery 使ってるサンプルが多かった。
とりあえず ContentResolver#query() にしてお茶を濁して、
Froyo 以降を対象にした場合の最適解があればそちらに移行しようかと。
コンテンツプロバイダーがなんかややこしくてわかりづらいのはぼくだけ・・・?
手持ちの Galaxy S 2.3.6 ではとりあえず動いてます。