Androidプリインストールアプリ「Contacts」にContentResolverでアクセス

こんにちは。
Androidアプリ開発時におけるセキュアに関する事例として、Androidプリインストールアプリ「Contacts（電話帳）」に登録したデータを取得するアプリを作ってみました。

#あらかじめ注目してもらいたい箇所#

サンプルコードを掲載しますが、前もって注目してもらいたい箇所を示します。

- マニフェストファイル
    - `<uses-permission android:name="android.permission.READ_CONTACTS" />`
- Activity
    - 標準APIで提供されている定数
        - `ContactsContract.Contacts.CONTENT_URI`
        - `ContactsContract.Contacts._ID`
        - `ContactsContract.Contacts.DISPLAY_NAME`　など
    - ContentResolverを使用する

#マニフェストファイル#

ポイントは、`<uses-permission android:name="android.permission.READ_CONTACTS" />`です。

```xml:AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.co.casareal.getcontactsdata">

    <!-- 電話帳を読み込むパーミッション -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
```

#Javaプログラム#

サンプルコードはActivityですが、別にActivityでなくてもかまいません。

```java:MainActivity.java
public class MainActivity extends Activity {
    // リクエストコード
    private static final int REQUEST_CODE_PHONE_NUMBER = 0;
    private TextView textName;
    private TextView textPhoneNumber;
    private Button buttonGetPhoneNumber;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 電話帳アプリのURIは標準APIで定数で提供されている
        Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
        startActivityForResult(intent, REQUEST_CODE_PHONE_NUMBER);
    }

    /**
     * startActivityForResultによる起動したActivityから戻ってきての処理
     */
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode != REQUEST_CODE_PHONE_NUMBER) { // 一応、チェック
            return;
        }

        String[] phoneNumbers = new String[0];
        ContentResolver contentResolver = getContentResolver();
        Cursor cursor = contentResolver.query(data.getData(), null, null, null, null);
        String id = "";
        String name = "";
        if (cursor.moveToFirst()) {
            // 1.選択された人のidの取得
            id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            // 2.選択された人の名前の取得
            name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

            // 3.選択された人の電話番号をすべて取得
            Cursor phoneCurssor = contentResolver.query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    null,
                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id,
                    null,
                    null);
            if (phoneCurssor.moveToFirst()) {
                phoneNumbers = new String[phoneCurssor.getCount()];
                int count = 0;
                do {
                    phoneNumbers[count] = phoneCurssor.getString(
                            phoneCurssor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DATA));
                    count++;
                } while (phoneCurssor.moveToNext());
            }
            phoneCurssor.close();
        }
        cursor.close();

        // 電話帳から取得した電話帳の名前
        Log.v("Contactsから取得した電話帳の名前", name);

        if (phoneNumbers.length > 0) {
            // 電話帳から取得した電話番号
            Log.v("Contactsから取得した電話番号", phoneNumbers[0]);
        }
    }
}
```

レイアウトファイルなどは掲載を略しています。`Log`で目視確認するだけでなく、適用にレイアウトファイルを作ってUI上で確認してみてください。

#動作確認#

1. このアプリをインストール。
2. 電話帳アプリで数人の登録をする。
3. このアプリを起動する。

の順で試してみてください。

#まとめ#

**意外と簡単に**プリインストールアプリ「Contacts（電話帳）」の保持するデータを取得できます。

以上です。