エクスポート (0) 印刷
すべて展開
情報
要求されたトピックは次のとおりです。しかし、このトピックはこのライブラリには含まれていません。

Windows Phone 8 のカスタム連絡先ストアの基本操作の実行方法

2014/06/18

対象: Windows Phone 8 および Windows Phone Silverlight 8.1 のみ

このトピックでは、アプリケーションのカスタム連絡先ストアの作成方法と、連絡先に対する基本的な操作方法 (追加、更新、削除など) について説明します。

このトピックは、次のセクションで構成されています。

メモメモ:

カスタム連絡先ストアの API は、アプリで作成された連絡先へのアクセスのみを提供します。アプリに電話機の連絡先ストアまたはカレンダーへの読み取りアクセスが必要な場合は、別の API を使用してください。詳細については、「Windows Phone 8 の連絡先とカレンダーへの読み取り専用アクセス」を参照してください。

各 Windows Phone アプリケーションには連絡先ストアを 1 つ作成できます。ストアを開くには CreateOrOpenAsync を呼び出します。このメソッドの呼び出し時に、ストアがまだ存在していなければ、新しく作成されます。このメソッドのオーバーロードされたバージョンは、ContactStoreSystemAccessMode 列挙体のメンバーと ContactStoreApplicationAccessMode 列挙体のメンバーを受け入れます。これらのメンバーは、システムやその他のアプリに対して連絡先ストアへのアクセスの範囲を指定します。ContactStoreSystemAccessMode.ReadOnly は、自分のアプリケーションだけに連絡先の変更を許可することを示します。ContactStoreSystemAccessMode.ReadWrite は、電話がその組み込みの連絡先エクスペリエンスを通して連絡先を変更できることを示します。ContactStoreApplicationAccessMode.LimitedReadOnly は、その他のアプリケーションができることは連絡先の表示名とプロフィールの写真を読み取ることだけであることを示しています。ContactStoreApplicationAccessMode.ReadOnly は、その他のアプリケーションが連絡先のプロパティをすべて読み取ることができることを示しています。既定の設定は、ContactStoreSystemAccessMode.ReadOnlyContactStoreApplicationAccessMode.LimitedReadOnly です。


ContactStore store = await ContactStore.CreateOrOpenAsync();



ContactStore store = await ContactStore.CreateOrOpenAsync(
    ContactStoreSystemAccessMode.ReadWrite,
    ContactStoreApplicationAccessMode.ReadOnly);


連絡先ストアを開いた後、StoredContactコンストラクターを呼び出して、連絡先ストアへの参照を渡すことで、新しい連絡先を作成します。StoredContact オブジェクトでは、連絡先データのいくつかの共通要素 (名や姓など) にビルトイン プロパティが定義されています。各連絡先には、オペレーティング システムによって動的に割り当てられるローカル ID を収めるフィールドと、アプリケーションで設定できるリモート ID を収めるフィールドがあります。リモート ID とローカル ID を使用すれば、電話のアプリケーションの連絡先ストア内の連絡先を、クラウド上のリモート連絡先ストアと関連付けることができます。

注意注意:

アプリが ContactStore API を使用しており、また StoredContact.RemoteId プロパティを使用して電話に保管された連絡先をリモートに保管された連絡先とリンクする場合は、RemoteId プロパティの値を不変かつ一意のものにすることが必要不可欠です。つまり、リモート ID が一貫して単一のユーザー アカウントを識別する必要があり、また電話上の他の連絡先 (他のアプリが所有する連絡先も含む) のリモート ID と競合しないことを保証するためにリモート ID に一意のタグが含まれている必要があります。RemoteId プロパティに一意の値が設定されていない StoredContact を保存しようとすると、保存操作は失敗することがあります。

アプリが使用するリモート ID が不変かつ一意であることが保証されない場合は、このトピックで後述する RemoteIdHelper クラスを使用して、リモート ID をシステムに追加する前に、すべてのリモート ID に一意のタグを追加できます。または、RemoteId プロパティを一切使用せず、代わりに、連絡先のリモート ID を保管するためのカスタム拡張プロパティを作成することもできます。

StoredContact オブジェクトで提供されるフィールドに加えて、GetExtendedPropertiesAsyncを呼び出してさらにプロパティを追加することができます。このメソッドは、連絡先データを入力できるキー値ペアの辞書を返します。フィールドと電話の内部連絡先プロパティ名との一貫性をもたせたい場合、キー値に KnownContactProperties クラスのフィールドを使用できます。または、任意の文字列をキーとして指定してもかまいません。連絡先にプロパティを設定したら、SaveAsync を呼び出してストアに保存します。

次のコードは、連絡先を追加する単純な実装方法を示しています。


async public void AddContact(string remoteId, string givenName, string familyName, string email, string codeName)
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();

    StoredContact contact = new StoredContact(store);

    RemoteIdHelper remoteIDHelper = new RemoteIdHelper();
    contact.RemoteId = await remoteIDHelper.GetTaggedRemoteId(store, remoteId);

    contact.GivenName = givenName;
    contact.FamilyName = familyName;

    IDictionary<string, object> props = await contact.GetPropertiesAsync();
    props.Add(KnownContactProperties.Email, email);

    IDictionary<string, object> extprops = await contact.GetExtendedPropertiesAsync();
    extprops.Add("Codename", codeName);

    await contact.SaveAsync();

}


連絡先は、ストアから当該連絡先を取得し、そのプロパティを変更し、保存することで更新できます。次のコード例では、FindContactByRemoteIdAsync を使用し、連絡先をそのリモート ID を用いて取得しています。FindContactByLocalIdAsync を呼び出して、ローカル ID で連絡先を取得することもできます。次に、連絡先のプロパティが変更され、SaveAsync が呼び出されて、変更された連絡先がストアに保存されます。


async private void UpdateContact(string remoteId, string givenName, string familyName, string email, string codeName)
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();

    RemoteIdHelper remoteIDHelper = new RemoteIdHelper();
    string taggedRemoteId = await remoteIDHelper.GetTaggedRemoteId(store, remoteId);
    StoredContact contact = await store.FindContactByRemoteIdAsync(taggedRemoteId);

    if (contact != null)
    {
        contact.GivenName = givenName;
        contact.FamilyName = familyName;

        IDictionary<string, object> props = await contact.GetPropertiesAsync();
        props[KnownContactProperties.Email] = email;

        IDictionary<string, object> extprops = await contact.GetExtendedPropertiesAsync();
        extprops["Codename"] = codeName;

        await contact.SaveAsync();
    }
}


連絡先を削除するには、DeleteContactAsync を呼び出して、削除対象の連絡先のローカル ID を渡します。リモート ID を使って連絡先を削除するには、FindContactByRemoteIdAsync を呼び出してから、Id プロパティの値を使って DeleteContactAsync を呼び出します。


async private void DeleteContact(string id)
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();
    await store.DeleteContactAsync(id);   
}


ストア内の全連絡先を照会するには、CreateContactQuery を呼び出します。引数を付けずにこのメソッドを使用した場合には、連絡先ごとに既定のフィールドセットが返され、既定の順序が使用されます。返された ContactQueryResult オブジェクトに対して GetContactsAsync を呼び出し、返された連絡先の一覧を取得します。


async private void DefaultQuery()
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();
    ContactQueryResult result = store.CreateContactQuery();
    IReadOnlyList<StoredContact> contacts = await result.GetContactsAsync();

    ContactListBox.ItemsSource = contacts;

}


アクセスする必要があるとわかっている KnownContactProperties のサブセットがある場合は、新規 ContactQueryOptions を作成してから、DesiredFields ベクターにプロパティ名を追加して、照会の作成時にフェッチする必要があることを指定できます。それでも GetPropertiesAsync を呼び出してフィールド値にアクセスする必要がありますが、データベースへの余分な照会がなくなるため、目的のフィールドを指定することでパフォーマンスを最適化できます。

OrderBy を設定して結果の順序付けに使用するフィールドを変更することもできますが、アプリ全般にわたる一貫したユーザー エクスペリエンスを維持するため、既定の順序を使用することをお勧めします。


async private void QueryWithDesiredFields()
{
    ContactStore store = await ContactStore.CreateOrOpenAsync();

    ContactQueryOptions options = new ContactQueryOptions();
    options.DesiredFields.Add(KnownContactProperties.Email);

    ContactQueryResult result = store.CreateContactQuery(options);
    IReadOnlyList<StoredContact> contacts = await result.GetContactsAsync();

    ContactListBox.ItemsSource = contacts;
}


上記のとおり、カスタム連絡先の RemoteId フィールドを使用するには、ID 値が電話上のすべてのアプリで一意であることを保証する必要があります。クラウド ベースの連絡先ストアが、一意であることが保証される ID を使用していない場合は、ストアに連絡先を保存する前に ID に一意のタグを追加できるようにする次のクラスをプロジェクトに追加できます。このクラスは、ストアから ID を取得した後に ID から一意のタグを削除して、元のリモート ID を復元できるようにもします。次に、RemoteIdHelper クラスの定義を示します。


class RemoteIdHelper
{
    private const string ContactStoreLocalInstanceIdKey = "LocalInstanceId";

    public async Task SetRemoteIdGuid(ContactStore store)
    {
        IDictionary<string, object> properties;
        properties = await store.LoadExtendedPropertiesAsync().AsTask<IDictionary<string, object>>();
        if (!properties.ContainsKey(ContactStoreLocalInstanceIdKey))
        {
            // the given store does not have a local instance id so set one against store extended properties
            Guid guid = Guid.NewGuid();
            properties.Add(ContactStoreLocalInstanceIdKey, guid.ToString());
            System.Collections.ObjectModel.ReadOnlyDictionary<string, object> readonlyProperties = new System.Collections.ObjectModel.ReadOnlyDictionary<string, object>(properties);
            await store.SaveExtendedPropertiesAsync(readonlyProperties).AsTask();
        }
    }

    public async Task<string> GetTaggedRemoteId(ContactStore store, string remoteId)
    {
        string taggedRemoteId = string.Empty;

        System.Collections.Generic.IDictionary<string, object> properties;
        properties = await store.LoadExtendedPropertiesAsync().AsTask<System.Collections.Generic.IDictionary<string, object>>();
        if (properties.ContainsKey(ContactStoreLocalInstanceIdKey))
        {
            taggedRemoteId = string.Format("{0}_{1}", properties[ContactStoreLocalInstanceIdKey], remoteId);
        }
        else
        {
            // handle error condition
        }

        return taggedRemoteId;
    }

    public async Task<string> GetUntaggedRemoteId(ContactStore store, string taggedRemoteId)
    {
        string remoteId = string.Empty;

        System.Collections.Generic.IDictionary<string, object> properties;
        properties = await store.LoadExtendedPropertiesAsync().AsTask<System.Collections.Generic.IDictionary<string, object>>();
        if (properties.ContainsKey(ContactStoreLocalInstanceIdKey))
        {
            string localInstanceId = properties[ContactStoreLocalInstanceIdKey] as string;
            if (taggedRemoteId.Length > localInstanceId.Length + 1)
            {
                remoteId = taggedRemoteId.Substring(localInstanceId.Length + 1);
            }
        }
        else
        {
            // handle error condition
        }

        return remoteId;
    }

}


ストアに連絡先を保存する前に、新規 RemoteIdHelper を作成し、SetRemoteIdGuid を呼び出します。これにより、アプリ用の GUID が作成され、連絡先ストアの拡張プロパティにその GUID が保管されます。このメソッドは複数回呼び出すこともできます。GUID が既に存在する場合は、オーバーライドされません。


ContactStore store = await ContactStore.CreateOrOpenAsync();
RemoteIdHelper remoteIdHelper = new RemoteIdHelper();
await remoteIdHelper.SetRemoteIdGuid(store);


リモート ID を使用した操作を実行する必要があるときはいつでも、まず GetTaggedRemoteId にリモート ID を渡して、アプリの GUID が付加された ID のコピーを取得します。

連絡先ストアに保存されたリモート ID から元のリモート ID を取得する必要が生じた場合には、一意のタグを削除して元の ID を返す GetUntaggedRemoteId を呼び出します。


string untaggedRemoteId = await remoteIdHelper.GetUntaggedRemoteId(store, taggedRemoteId);
UpdateRemoteContact(untaggedRemoteId, contact);


vCard は、電子名刺に使用される標準ファイル形式です。ContactInformation クラスは ParseVcardAsnc メソッドを公開し、このメソッドは指定された URI で非同期に vCard を解析して、作成された ContactInformation オブジェクトを返します。このオブジェクトと、連絡先ストアへの参照とを StoredContact コンストラクターに引き渡した後、SaveAsync を呼び出して連絡先を保存します。

次のサンプル コードは、vCard からカスタム連絡先ストアに連絡先を保存する方法を示しています。

task<StoredContact^> SaveFromVcard(ContactStore^ store, String^ uriToVcard)
{
    // Invoke the parser on the passed-in URI.
    return create_task(ContactInformation::ParseVcardAsync(ref new Uri(uriToVcard)))
    .then([=] (ContactInformation^ info) -> StoredContact^
    {
        // When that's done, wrap a stored contact around it, save.
        auto contact = ref new StoredContact(store, info);
        create_task(contact->SaveAsync()).get();

        return contact;
    });
}

表示:
© 2014 Microsoft