2012年11月5日月曜日

コンタクトの追加方法

Androidのコンタクトのアクセス方法はAPI Level5から変更されている。
古いAPIでの追加方法はこんな感じ

ContentValues values = new ContentValues();
values.put(android.provider.Contacts.People.NAME, "ほげ たろう");
final Uri uri = getContentResolver().insert(android.provider.Contacts.People.CONTENT_URI, values);

API Level5以降からはContractsが非推奨になっていて、代わりにContactsContractを使う。
ContractsContractを使ったコンタクトの読み書きはSDK付属のサンプルコードContactManagerを見れば参考になる。
登録部分はこんな感じ。

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName())
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Email.DATA, email)
.withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType)
.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
      //省略
}
しかしこのコードをエミュレータで実行するとうまく動かない。
原因はこの方式でコンタクトを追加するにはACCOUNT_TYPE、ACCOUNT_NAMEを取得する必要があるが
エミュレータの初期状態ではアカウントがないためと考えられる。

このアカウントはAccountManagerが管理しているものでGmailアカウントやらtwitterアカウントがこれに該当する。
実機(GalaxyS)でやるとコンタクトを登録できるが、アカウントをGmail等にして登録すると登録自体は成功するがInvisible扱いとなって電話帳に追加されない。

この問題は、かの有名なStackoverflowでも取り上げられておりそれによるとACCOUNT_TYPE,NAMEを以下のようにnullにして設定すると良いらしい。
// .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())
// .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName())
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
これでとりあえず一見動くようになったが機種によってどうなるかよく分からない状態。

参考サイト
http://developer.android.com/resources/articles/contacts.html
http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html
http://stackoverflow.com/questions/3336019/new-contacts-created-using-contactscontract-do-not-appear-in-contacts-app

0 件のコメント:

コメントを投稿