UserProfileを取得する


Android4.0(ICS)から、Androidは所有者の個人情報(UserProfile)を持つようになりました。

UserProfileは、Peopleアプリケーションを初めて起動した時に登録を促されます。
スクリーンショットはPeopleアプリケーションでのUserProfile登録画面

本エントリでは、この新たに追加されたUserProfileを読み出す方法を紹介します。
紹介するAPI一覧はこちら

新規API概要
ContactsContract.Profile.CONTENT_URIProfileのCONTENT_URI情報
ContactsContract.Profile.DISPLAY_NAMEユーザ名のフィールド
ContactsContract.Profile.HAS_PHONE_NUMBER電話番号を持っているかを表すフィールド。"0"なら非保持、"1"なら保持

また、本エントリはコンテンツプロバイダを利用します。
TechBoosterでは以下の記事で取り扱っています。参考にどうぞ。

ContentProviderからデータを取得する
ContentProviderで端末内の画像データを取得する
ContentProviderで通話履歴を取得する

それでは続きをどうぞ。

パーミッションを設定する

UserProfileを保持するコンテンツプロバイダにアクセスするために、以下のパーミッションが新たに追加されました。

追加されたパーミッション概要
WRITE_PROFILEProfileの書き込み権限
READ_PROFILEProfileの読み取り権限

これらのパーミッションは従来通り、設定されていないとアクセス権限エラーでエラー終了するため、
UserProfileにアクセスする際には必ず付与するようにしましょう。

※UserProfileにアクセスすることは、ユーザの個人情報にアクセスすることに繋がります。
※自己防衛のため、ユーザはWRITE_PROFILEやREAD_PROFILEを持つアプリケーションを積極的にインストールしないかもしれません。

<manifest 省略>
	<uses-permission android:name="android.permission.WRITE_PROFILE" />	<uses-permission android:name="android.permission.READ_CONTACTS" />
        ...省略

UserProfileにアクセスする

UserProfileにアクセスするためには、以下の手順を取る必要があります。

1.Content_URIからCursorを取得する。
2.目的のフィールドからデータを取得する。

1.Content_URIからCursorを取得する。

データベースへのアクセスと同様に、Cursorを取得します。
UserProfileにアクセスする際に使用する、コンテントプロバイダのURIは以下の通り。

追加されたURI概要
ContactsContract.Profile.CONTENT_URIProfileが保存されているURIを指す

表内のAPIを用いて、以下ソースコード2行目の様にCursorを取得します。
また、取得したCursorはデータの先頭を指すように移動させておきます。

		// Cursorの取得
		Cursor mCursor = getContentResolver().query(ContactsContract.Profile.CONTENT_URI, null, null, null, null);

		mCursor.moveToFirst();

2.目的のフィールドからデータを取得する。

UserProfileクラスが持つ、フィールド名の一部を以下の表に表します。
その他のフィールドについては、リンク先のInherited Constantsの項を参考にしてください。

フィールド名概要
DISPLAY_NAME そのレコードのユーザ名
HAS_PHONE_NUMBERそのレコードに電話番号を持つかどうか
IS_USER_PROFILEそのレコードがUserProfileであるかどうか
PHOTO_THUMBNAIL_URIそのレコードのユーザのサムネイル画像のURI
PHOTO_URIそのレコードのユーザの画像のURI

表で例に取り上げたフィールド名を利用し、ユーザ名を取得するソースコードは以下の通りです。
CursorクラスのgetColumnIndexメソッドに対しフィールド名を指定し、getStringメソッドでデータを取得しています。

		// UserName
		int nameIndex = mCursor.getColumnIndex(ContactsContract.Profile.DISPLAY_NAME);
		String uName = mCursor.getString(nameIndex);

サンプルソースコード

UserProfileに登録した、ユーザ名と電話番号を取得するサンプルコードは以下の通りです。
注意しなければいけない点は、ContactsContract.Profile.CONTENT_URIから取得したCursorでは電話番号が取得できない点です。

サンプルでは、UserProfileからIDを取得し、ContentProviderからデータを取得するで紹介したContactsContract.CommonDataKinds.Phoneクラスを利用し電話番号を取得しています。

	@Override
	public void onClick(View v) {
		/* Get UserProfile */

		// Cursorの取得
		Cursor mCursor = getContentResolver().query(
				ContactsContract.Profile.CONTENT_URI, null, null, null, null);

		mCursor.moveToFirst();

		// UserNameの取得
		int nameIndex = mCursor
				.getColumnIndex(ContactsContract.Profile.DISPLAY_NAME);
		String uName = mCursor.getString(nameIndex);

		// Phone Numberの取得
		int hasPhoneNumIndex = mCursor
				.getColumnIndex(ContactsContract.Profile.HAS_PHONE_NUMBER);
		String hasNumber = mCursor.getString(hasPhoneNumIndex);

		// ProfileレコードのIDを取得する
		int idIndex = mCursor.getColumnIndex(ContactsContract.Profile._ID);
		long _id = mCursor.getLong(idIndex);

		// ProfileのURLから取得したCursorを閉じる
		mCursor.close();

		String phoneNumber = "No Data";
		// 取得したIDからNumberの取得
		if (hasNumber.equals("1")) {

			// ProfileのContent_Uriから取得したIDから、Phone情報のUriを取得する
			Uri pUri = ContentUris.withAppendedId(
					ContactsContract.CommonDataKinds.Phone.CONTENT_URI, _id);

			// UriからCursorを取り出す
			mCursor = managedQuery(pUri, null, null, null, null);
			mCursor.moveToFirst();

			// Cursorを使い、PhoneNumberを取得する
			phoneNumber = mCursor
					.getString(mCursor
							.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

			// Close Cursor
			mCursor.close();

		}

		// TextViewを表示する
		StringBuilder sb = new StringBuilder();
		sb.append("User Name : ");
		sb.append(uName);
		sb.append("\n");
		sb.append("Phone Number : ");
		sb.append("\n");
		sb.append(phoneNumber);

		tv.setText(sb.toString());
	}

実行結果は以下のスクリーンショットのとおりです。
期待通りに、ユーザ名と電話番号が取得できています。