fc2ブログ

記事一覧

アドレス帳から名前と生年月日とメールアドレスを取得する方法 | Xamarin.Forms


今回はXamarin.Formsで連絡先(アドレス帳)を読み取るプログラミング方法についてご紹介いたします。AndroidとiOSで共通で処理できるように毎度お馴染みDependencyServiceで記述します。どちらもContactsというサービスが導入されているようで、Contactsからデータを取得する際に条件やフィールドを設定することがキーポイントとなります。



前提条件
・Windows10 Pro 64Bit
・Visual Studio 2015 Community Update3
・Xamarin 4.4.0.34 (NuGet Xamarin.Forms 2.3.4.247)
・macOS Sierra 10.12.4 / Xcode8.3.1 / Xamarin.iOS 10.8.0.1



1.PCLの記述方法

PCLプロジェクト内にDependencyServiceで呼び出すためのインターフェースを配置します。
AndroidとiOSで共通で使用するため共通のList型で返します。
IContactsService.cs
namespace AppName.Services
{
    //DependencyServiceから利用する
    public interface IContactsService
    {
        List<UserInfo> GetAddressList();
    }
}



2.iOSの実装方法

iOSプロジェクト内に以下のクラスを配置します。
連絡先を読み取るために以下のブロックをinfo.plistに追加します。
info.plist
<key>NSContactsUsageDescription</key>
<string>連絡帳を利用します。</string>

ContactsService.cs
using System;
using System.Collections.Generic;
using Foundation;
using UIKit;
using Contacts;
using Xamarin.Forms;
[assembly: Dependency(typeof(ContactsService))]
namespace AppName.iOS.Services
{
    public class ContactsService : IContactsService
    {
        public List<UserInfo> GetAddressList()
        {
            List<UserInfo> userList = new List<UserInfo>();
            try
            {
                //iOSバージョン9以降からのみ
                if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
                {
                    NSError error;
                    var ContainerId = new CNContactStore().DefaultContainerIdentifier;
                    var predicate = CNContact.GetPredicateForContactsInContainer(ContainerId);

                    // 取得したいフィールドを設定
                    var fetchKeys = new NSString[] { CNContactKey.GivenName,    //FirstName
                                                     CNContactKey.FamilyName,   //LastName
                                                     CNContactKey.PhoneticGivenName,    //FirstNameKana
                                                     CNContactKey.PhoneticFamilyName,   //LastNameKana
                                                     CNContactKey.EmailAddresses,
                                                     CNContactKey.PhoneNumbers,
                                                     CNContactKey.PostalAddresses,
                                                     CNContactKey.Birthday,
                                                     CNContactKey.Dates,
                                                     CNContactKey.DepartmentName,
                                                     CNContactKey.JobTitle,
                                                     CNContactKey.MiddleName,
                                                     CNContactKey.Note,
                                                     CNContactKey.OrganizationName
                                                    };

                    //全ての連絡先を取得する
                    var store = new CNContactStore();
                    var contacts = store.GetUnifiedContacts(predicate, fetchKeys, out error);

                    if (contacts != null && contacts.Length > 0)
                    {
                        //登録されている連絡先の数だけループする
                        foreach (var contact in contacts)
                        {
                            UserInfo uInfo = new UserInfo();
                            // データ取得
                            uInfo.FirstName = contact.GivenName;
                            uInfo.LastName = contact.FamilyName;
                            uInfo.FirstNameKana = contact.PhoneticGivenName;
                            uInfo.LastNameKana = contact.PhoneticFamilyName;
                            if (contact.EmailAddresses != null && contact.EmailAddresses.Length > 0)
                            {
//メールアドレスの取得
                                uInfo.Email = contact.EmailAddresses.FirstOrDefault().Value;
                            }
                            uInfo.BirthDay = new DateTimeOffset(new DateTime((int)contact.Birthday.Year,
                                                                             (int)contact.Birthday.Month,
                                                                             (int)contact.Birthday.Day));
                            userList.Add(uInfo);
                        }
                    }
                }
                else
                {
                    //iOSバージョン8以下はAddressBookを使用してください
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message + System.Environment.NewLine + ex.StackTrace);
            }
            return userList;
        }
    }
}



3.Androidの実装方法

連絡先を読み取るためのパーミッションを設定します。
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />

Androidプロジェクト内に以下のクラスを配置します。
ContactsService.cs
using System;
using System.Collections.Generic;
using Android.Database;
using Android.Provider;
using Xamarin.Forms;
[assembly Dependency(typeof(ContactsService))]
Namespace AppName.Droid.Services
{
    Public Class ContactsService :  IContactsService
    {
        Public List<UserInfo> GetAddressList()
        {
            List<UserInfo> userList = New List<UserInfo>();
           
            //カーソル取得列
            String[] columns = {
                                ContactsContract.Contacts.InterfaceConsts.Id,
                                ContactsContract.Contacts.InterfaceConsts.DisplayName,
                                ContactsContract.Contacts.InterfaceConsts.PhoneticName,
                                ContactsContract.CommonDataKinds.Event.StartDate,
                                ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId,
                                };

            String where = String.Empty;
            //カーソル条件 (誕生日のデータがある連絡先のみに指定しています。)
            where = ContactsContract.Data.InterfaceConsts.Mimetype + " = '" + ContactsContract.CommonDataKinds.Event.ContentItemType + "' AND " +
                    ContactsContract.CommonDataKinds.Event.InterfaceConsts.Type + "=" + (int)EventDataKind.Birthday;

            String[] selectionArgs = null;
            String sortOrder = ContactsContract.Contacts.InterfaceConsts.DisplayName;

            //生年月日のデータを取得するカーソル
            var cursor = Forms.Context.ContentResolver.Query(ContactsContract.Data.ContentUri, columns, where, selectionArgs, sortOrder);

            If (cursor.Count > 0)
            {
                While (cursor.MoveToNext())
                {
                    UserInfo uInfo = New UserInfo();                   
                    //IDの取得(取得のみ/使用しない)
                    String id = cursor.GetString(cursor.GetColumnIndex(columns[0]));

                    //名前の取得
                    uInfo.Name = cursor.GetString(cursor.GetColumnIndex(columns[1]));
                    uInfo.Kana = cursor.GetString(cursor.GetColumnIndex(columns[2]));
       
                    //メールアドレスの取得
                    String emailId = cursor.GetString(cursor.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId));   //(メールアドレス検索用)
                    String email = String.Empty;
                    ICursor eCursor = Forms.Context.ContentResolver.Query(
                                            ContactsContract.CommonDataKinds.Email.ContentUri,
                                            null,
                                            ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId + " = ? ",
                                            New String[] { emailId },
                                            null);
                    While (eCursor.MoveToNext())
                    {
                        email = eCursor.GetString(eCursor.GetColumnIndex(ContactsContract.CommonDataKinds.Email.Address));
                        break;
                    }
                    eCursor.Close();
                    uInfo.Email = email;

                    //誕生日の取得
                    String birthday = cursor.GetString(cursor.GetColumnIndex(ContactsContract.CommonDataKinds.Event.StartDate));
DateTime dt;
                    If (!String.IsNullOrEmpty(birthday) &&
DateTime.TryParse(birthday, out dt)) //yyyy-MM-dd形式で取得できます。
                    {
                        uInfo.BirthDay = New DateTimeOffset(dt);
                    }

//戻り値のListに追加する
friendList.Add(fInfo);
                }
            }
            cursor.Close();
            cursor = null;

            Return userList;
        }
       
    }
}



4.使用方法

PCLプロジェクトの中の任意のページに記述します。
TestPage.xaml.cs
using AppName.Services;
using Xamarin.Forms;
public partial class TestPage : ContentPage
{
void OnButtomClick(object sender, EventArgs e)
{
    List<UserInfo> userList = DependencyService.Get<IContactsService>().GetAddressList();
}
}

※個人情報を保存するViewModelクラスのUserInfoは自作してくださいね。



当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
https://itblog.dynaspo.com/blog-entry-81.html


関連記事

コメント

コメントの投稿

※名前とタイトルが入力されていないコメントでは他のコメントとの区別ができません。

 入力されていないコメントには返信しませんのであらかじめご了承くださいませ。

※ニックネームでも良いので必ずご入力ください。

    

※必ずご入力ください。

    
    

※必ずご入力ください。

※技術的な質問には環境やエラーについて正確かつ詳細にお教えください。

・正確なエラーの内容

・Windowsのバージョン番号

・Visual Studioのバージョン

・機器の型番

・アプリやソフトのバージョン

    

カテゴリ別記事一覧

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Catalina 10.15 / Mojave 10.14 / High Sierra 10.13 / Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
【データベース】
Oracle 10g/9i
SQLServer 2016/2008R2/2005/2000
SQLAnywhere 16/11/8
【BI/レポートツール】
Cognos ReportNet (IBM)
Microsoft PowerBI
ActiveReport (GrapeCity)
CrystalReport
【OCX関連】
GrapeCity InputMan SPREAD MultiRow GridView
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS jQuery IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。