#はじめに
軽い気持ちでXamarinに手を出したら結構詰まったので,忘備録を兼ねて情報共有する.基本的なことすぎるが,意外に時間のかかったところであった.
筆者の環境は
- Windows10
- VisualStudio2017 enterprise
- MonoAndroid,Version=v8.0
#Android固有の機能にアクセスする
##今回アクセスしたい機能
PCL内にあるソースコードから各OSに依存した機能を使いたい場合が多く存在すると思われる.筆者の場合,とりあえず端末が接続しているWifiのSSIDを取得したかった.またAndroidでWifiに関係した情報を取得する際は,Android.Net.Wifi.WifiManagerクラスを使って以下のコードを書けばよい.
var wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(Context.WifiService);
//SSIDとBSSIDの取得
var ssid = wifiManager.ConnectionInfo.SSID;
var bssid = wifiManager.ConnectionInfo.BSSID;
このコードでとりあえずはSSIDなどが取得できる(少し整形する必要もある)が,このコードをPCL内に書いても動かない.例えば,hogehoge.xaml.csに上のコードを書いても動かない.
##解決策
PCLのプロジェクト内にインターフェースを作ることによって解決する.
PCL内に適当なクラスを追加(今回はWificonnection.cs)し,以下のようにインターフェースを定義する.
public interface IWificonnection
{
//SSIDを取得
string GetSSID();
}
インターフェースを定義したら,それを実装するためにAndroidのプロジェクトに実装用のクラスを作成する.
using System;
using Android.Content;
using Android.Net.Wifi;
using Xamarin.Forms;
[assembly: Dependency (typeof(SolutionName.Droid.WifiInfo))]
namespace SolutionName.Droid
{
public class WifiInfo : IWificonnection
{
/// <summary>
/// Get current wifi SSID
/// </summary>
/// <returns>returns SSID (if wifi is not available, it returns String.Enpty.)</returns>
public string GetSSID()
{
var wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(Context.WifiService);
var ssid = wifiManager.ConnectionInfo.SSID;
var bssid = wifiManager.ConnectionInfo.BSSID;
if (!String.IsNullOrEmpty(ssid) && ssid != "<unknown ssid>")
{
return ssid.Trim(' ', '"');
}
if (!String.IsNullOrEmpty(bssid))
{
return bssid.Trim(' ', '"');
}
return String.Empty;
}
}
}
普通にインターフェースを実装しても使えるわけではなく,
[assembly: Dependency (typeof(SolutionName.Droid.WifiInfo))]
これがないと実際にこの機能を利用をする際に例外を吐くようになる.
最後に,実際にWifiのSSIDを取得するGetSSID()をPCL内で実行する.
var ssid = DependencyService.Get<IWificonnection>().GetSSID();
DependencyServiceを利用してインターフェースを指定し,実装されたメソッドを実行できるようになる.
#最後に
今回はAndroidでの例だったが,iOSでも同じような手順でできるようである.残念ながら筆者はMacの環境を所持していないのでまだ試せていない.
こんな初歩的なところで詰まってしまう筆者は「Xamarinの世界は深い…」と感じた