はじめに
先日、JXUG Xamarin.iOS & Xamarin.Androidハンズオン! - connpassへ参加させていただき、 Java→C#(Xamarin.Android)へ変換する際のコツを学ばさせていただきました。 (後ほど参加レポート書きたいと思います。)
またプライベートで、
という事を行いたい方がいて、目ぼしいアプリが見つからないとのことを聞き、 これはXamarin.Androidアプリを作ってみるのにちょうどいいのでは? ( ̄ー ̄)ニヤリ と思い、作成しました。
実装概要は以下です。
プライベート的なあれで申し訳ないのですが、iOS側のみ動作未確認です。。。
※近々、SimなしiPhone買って、動作確認しようかと思います。 Androidは動作確認済みです。
Xamarinとは?
ざっくり説明すると、Android,iOS,WindowsアプリをC#で 実装できるクロスプラットフォーム開発環境のことです。
詳しくは、エクセルソフト田淵さんがまとめてくださった、 こちらの記事をご参照ください。
Visual Studio 2017でのXamarinインストール手順も記述してくださっていますので、 新規に始める方におすすめです。
解説
今回解説するのは、Xamarin.Androidでのアドレス帳へのアクセス方法です。 (Xamarin.iOSは動作確認後に投稿します。)
すでに同じような解説記事を書いてくださっている方がいらっしゃるのですが、
アドレス帳から名前と生年月日とメールアドレスを取得する方法 | Xamarin.Forms - ITブログ時々なんでもブログ
今回は、Android,iOS固有機能を実装する際のノウハウを積みたかったため、 基本的に自分で調べて実装を進めてみました。 実装するまでに踏んだ手順を記載しますので、参考にしていただければと思います。
Xamarin.Android側
Xamarin.Androidは連絡先プロバイダという機能を利用してアクセスします。
連絡先プロバイダは、Xamarinの公式ページでも軽く(英文で)説明してくれていますが、 きちんと理解されたい方(&自分と同じく英語に弱い同士)は、 Android Developerに記述された連絡先プロバイダについての説明文(日本語)を読みましょう。
連絡先プロバイダをざっくり理解感じ、SQLって感じですかね。。。
Androidのアドレス帳に登録する電話番号やメールアドレスって、 一人あたり複数個登録できますよね? なので、そういった項目を全て抽出したい場合は、 各(電話番号&メールアドレス)テーブルみたいのを参照してねー、 って感じで理解しました。
そんで、JavaのコードをXamarin.Android(C#)で記述したのが、 以下のコードになります。
/// <summary> /// アドレス帳取得 /// </summary> /// <returns></returns> public ObservableCollection<Contact> GetContactList() { ObservableCollection<Contact> list = new ObservableCollection<Contact>(); // アドレス帳から取得する名前を指定 string[] projection = { ContactsContract.Contacts.InterfaceConsts.Id, // ID(おそらくアドレス帳一意となる値) ContactsContract.Contacts.InterfaceConsts.DisplayName, // 名前 ContactsContract.Contacts.InterfaceConsts.PhoneticName, // 読みがな }; // アクティビティ取得 // Forms.Context から取得すると警告が発生するため、以下で取得するほうが良さそう var activity = Android.App.Application.Context; // アクティビティが取得できた場合にクエリ発行 if(activity != null) { var cursor = activity.ContentResolver.Query( ContactsContract.Contacts.ContentUri, //ContactsContract.Data.ContentUri, projection, string.Empty, null, ContactsContract.Contacts.InterfaceConsts.DisplayName ); if (0 < cursor.Count) { while (cursor.MoveToNext()) { Contact model = new Contact(); string id = cursor.GetString(cursor.GetColumnIndex(projection[0])); model.Name = cursor.GetString(cursor.GetColumnIndex(projection[1])); model.Kana = cursor.GetString(cursor.GetColumnIndex(projection[2])); model.Tel = GetTel(id, activity.ContentResolver); model.Email = GetEmail(id, activity.ContentResolver); list.Add(model); } } } return list; } /// <summary> /// 電話番号取得 /// </summary> /// <param name="id">ContactId</param> /// <param name="cr">Android.App.Application.Context.ContentResolver</param> /// <returns>'/'区切りの電話番号文字列</returns> private ObservableCollection<string> GetTel(string id, ContentResolver cr) { ObservableCollection<string> result = new ObservableCollection<string>(); var cursor = cr.Query( ContactsContract.CommonDataKinds.Phone.ContentUri, null, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + "=" + id, null, null ); if(0 < cursor.Count) { while(cursor.MoveToNext()) { string val = string.Empty; val = cursor.GetString(cursor.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.Number)); if(!string.IsNullOrEmpty(val)) { result.Add(val); } } } return result; } /// <summary> /// メールアドレス取得 /// </summary> /// <param name="id">ContactId</param> /// <param name="cr">Android.App.Application.Context.ContentResolver</param> /// <returns>'/'区切りのメールアドレス文字列</returns> private ObservableCollection<string> GetEmail(string id, ContentResolver cr) { ObservableCollection<string> result = new ObservableCollection<string>(); var cursor = cr.Query( ContactsContract.CommonDataKinds.Email.ContentUri, null, ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId + "=" + id, null, null ); if (0 < cursor.Count) { while (cursor.MoveToNext()) { string val = string.Empty; val = cursor.GetString(cursor.GetColumnIndex(ContactsContract.CommonDataKinds.Email.Address)); if (!string.IsNullOrEmpty(val)) { result.Add(val); } } } return result; }
<uses-permission android:name="android.permission.READ_CONTACTS" />
Xamarin.Android側を実装した感想
Java→C#への変換はそんなに大変ではないなーって感じでした。 連絡先プロバイダについて、Android Developerの説明も丁寧でしたし、 参考文献がない場合は、Xamarin.Androidは以下のように実装を進めてく方向がよさそうだな、 と思いました。