Twitter で、Justin Angel は、特定の連絡先の詳細を表示する ShowContactTask を起動できないという、既知の Windows Phone SDK の制限を回避できることをほのめかしました (この問題を解決するには、ここで投票してください)。これを機能させるために自分でテストをまとめましたが、ユーザーの名前が記載された空白のページしか表示されません。
誰かがこれを機能させる方法の例を持っている可能性はありますか?
前もって感謝します!
Twitter で、Justin Angel は、特定の連絡先の詳細を表示する ShowContactTask を起動できないという、既知の Windows Phone SDK の制限を回避できることをほのめかしました (この問題を解決するには、ここで投票してください)。これを機能させるために自分でテストをまとめましたが、ユーザーの名前が記載された空白のページしか表示されません。
誰かがこれを機能させる方法の例を持っている可能性はありますか?
前もって感謝します!
Twitter で言ったように、WP8 では、カスタマイズされたランチャー タスクまたは app2app カスタム プロトコルを介して連絡先の詳細を起動することはできません。
ピープル ハブは、連絡先の詳細画面と非常によく似た画面での vCard のインポートをサポートしています。この機能を使用して、主に vCard をインポートしたり、オプションで連絡先の詳細を表示したりできます (ただし、新しい連絡先として表示されます)。ピープル ハブの vCard app2app ファイルの関連付けは次のとおりです。
<Extensions>
<FileTypeAssociation Name="VCard" Category="phone.fileTypeAssociation" TaskID="ViewVCardContact" NavUriFragment="VCardMode=2&vCardFileToken=%s">
<Logos>
<Logo Size="small" IsResource="true">res://ContactsRes{ScreenResolution}!VCard.FileTypeIcon.Small.png</Logo>
<Logo Size="medium" IsResource="true">res://ContactsRes{ScreenResolution}!VCard.FileTypeIcon.Medium.png</Logo>
<Logo Size="large" IsResource="true">res://ContactsRes{ScreenResolution}!VCard.FileTypeIcon.Large.png</Logo>
</Logos>
<SupportedFileTypes>
<FileType ContentType="text/vcard">.vcf</FileType>
<FileType ContentType="text/x-vcard">.vcf</FileType>
</SupportedFileTypes>
</FileTypeAssociation>
</Extensions>
この app2app カスタム プロトコルを使用するために、vCard VCF ファイルを作成し、それを IsoStore に保存して、ピープル ハブで vCard を起動するコードを作成できます。
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var contacts = new Contacts();
contacts.SearchCompleted += contacts_SearchCompleted;
contacts.SearchAsync(string.Empty, FilterKind.None, null);
}
private async void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
// get a Contact and build a vCard for it
Contact contact = e.Results.First();
string vcard = GetContactVCard(contact);
Debug.WriteLine(vcard);
// write the vCard to IsoStore as a VCF file
using (var s = IsolatedStorageFile.GetUserStoreForApplication().CreateFile("myContact.vcf"))
using (var sw = new StreamWriter(s))
{
sw.Write(vcard);
}
// launch the VCF file
var vcardStorageFile = await ApplicationData.Current.LocalFolder.GetFileAsync("myContact.vcf");
Launcher.LaunchFileAsync(vcardStorageFile);
}
次に、vCard を作成する関数を実装する必要があります。Base64 埋め込み画像が必要なので、vCard バージョン 3.0 を使用します (詳細は後述)。ウィキペディアから vCard 3.0 形式をコピーしたので、この例には Microsoft 固有の拡張機能はありません。vCard をコードにコピーし、Contact クラスからいくつかのデータを注入しました。
private string GetContactVCard(Contact contact)
{
return string.Format(@"BEGIN:VCARD
VERSION:3.0
N:{0};{1}
FN:{2}
ORG:{3}
TITLE:{4}
PHOTO;TYPE=PNG;ENCODING=B:{9}
TEL;TYPE=WORK,VOICE:{5}
TEL;TYPE=HOME,VOICE:{6}
ADR;TYPE=WORK:;;{10}
ADR;TYPE=HOME:;;{11}
EMAIL;TYPE=PREF,INTERNET:{7}
REV:{8}
END:VCARD",
contact.CompleteName.LastName,
contact.CompleteName.FirstName,
contact.DisplayName,
contact.Companies.Any() ? contact.Companies.First().CompanyName : string.Empty,
contact.CompleteName.Title,
contact.PhoneNumbers.Any(p => p.Kind == PhoneNumberKind.Work) ? contact.PhoneNumbers.First(p => p.Kind == PhoneNumberKind.Work).PhoneNumber : string.Empty,
contact.PhoneNumbers.Any(p => p.Kind != PhoneNumberKind.Work) ? contact.PhoneNumbers.First(p => p.Kind != PhoneNumberKind.Work).PhoneNumber : string.Empty,
contact.EmailAddresses.Any() ? contact.EmailAddresses.First().EmailAddress : string.Empty,
DateTime.Now.ToFileTimeUtc(),
GetPhotoBase64(contact),
contact.Addresses.Any(a => a.Kind == AddressKind.Home) ? BuildAddress(contact.Addresses.First(a => a.Kind == AddressKind.Home).PhysicalAddress) : string.Empty,
contact.Addresses.Any(a => a.Kind == AddressKind.Work) ? BuildAddress(contact.Addresses.First(a => a.Kind == AddressKind.Work).PhysicalAddress) : string.Empty
);
}
このロジックを完成させるのにあまり時間を費やしていないことがわかります。いくつかのエッジ条件処理を追加して、StringBuilder に移行するのが最善かもしれません。次に、やや複雑なアドレス文字列を作成します。
private string BuildAddress(CivicAddress physicalAddress)
{
StringBuilder sb = new StringBuilder();
string[] address = new string[]
{
physicalAddress.AddressLine1,
physicalAddress.AddressLine2,
physicalAddress.City + " " + physicalAddress.StateProvince,
physicalAddress.CountryRegion,
physicalAddress.PostalCode
};
foreach (var line in address)
if (!string.IsNullOrEmpty(line))
sb.Append(line + ";");
return sb.ToString();
}
最後に、vCard の一部として画像を埋め込む必要があります。WP8 には連絡先の写真に使用できる URL がないため、base64 に連絡先の写真を埋め込んでいます。
private string GetPhotoBase64(Contact contact)
{
using (var picture = contact.GetPicture())
{
if (picture == null)
{
return null;
}
else
{
using (var sr = new StreamReader(picture))
{
byte[] data = new byte[picture.Length];
picture.Read(data, 0, data.Length);
return Convert.ToBase64String(data);
}
}
}
}
このコード スニペットを実行すると、連絡先のプロパティの詳細のほとんどがエクスポート/インポートされた vCard に引き継がれていることがわかります。