Xamarin逆引きTips
Xamarin.Formsで地図を表示するには?(Xamarin.Forms.Maps使用)
Android/iOSアプリで各プラットフォーム標準の地図を表示するには、Xamarin.Forms.Mapsコントロールを使う。その基本的な使い方を説明する。
スマートフォンの各プラットフォームでは、標準の地図機能が提供されており、Androidでは「Google Maps Android API v2」、iOSでは「MapKit」がそれである。Xamarin.Formsでは、この各プラットフォームの標準マップAPIを共通的に扱えるようにXamarin.Forms.Maps
コントロールが提供されている。
今回は、このXamarin.Forms.Maps
コントロールの利用方法について解説する*1。
- *1 なお本Tipsは、Windows上でVisual Studio 2013を使用してXamarin.Forms開発をすることを前提としている(※編集部注: Mac上のXamarin Studioでも同様の手順で、本稿の内容が実現できることは確認している)。使用しているXamarin.Formsのバージョンは、プロジェクト作成時に利用されている「1.3.1.6296」である。
1. シナリオ
Xamarin.Forms.Maps
コントロールを使用して地図を表示するためには、最初に、プラットフォーム側での初期化処理が必要である。そして、プラットフォームごとにパーミッションなどのいくつかの設定も必要になる。
今回は、これらの作業について、順を追って解説する。
2. Xamarin.Formsプロジェクトを作成する
メニューバーの[ファイル]-[新規作成]-[プロジェクト]から表示したダイアログで、[テンプレート]-[Visual C#]-[Mobile Apps]-[Blank App (Xamarin.Forms Portable)]を選択し、名前を「MapsSample」として[OK]ボタンを押す。
3. Xamarin.Forms.Mapsパッケージの追加
Xamarin.Forms.Maps
を使用するためには、NuGetパッケージのインストールが必要だ。
Visual StudioでのNuGetパッケージのインストールは、メニューバーの[ツール]-[NuGet パッケージマネージャー]-[ソリューションの NuGet パッケージの管理]を選択して表示された[NuGet パッケージの管理]ダイアログから行う。検索欄にXamarin.Forms.Mapsと入力すると、目的のパッケージを簡単に見つけることができる。また、依存関係を見ると分かるように、Xamarin.Formsの最新stableである1.3.5.6337や、Xamarin.GooglePlayServicesも同時にインストールされることになる。
図2の[インストール]ボタンを押した後、続いて表示される[プロジェクトの選択]ダイアログでは、全てのプロジェクトにチェックを入れて[OK]ボタンを押す(図3)。
実は、ここまでの要領でXamarin.Forms.Maps
パッケージのインストールは完了するはずなのだが、2015年3月9日現在、一部のプロジェクトでエラーが発生してインストールが失敗する(次の画面はその例)。
この問題を回避するためには、先のインストールを行う前に、以下の作業を順に行う必要がある。
- ソリューションエクスプローラーでAndroidプロジェクトを右クリックして表示されるメニューから[プロパティ](=プロジェクトのプロパティ)を選択し、図5のように[Application]の[Compile using Android version]を
Use Latest Platform (API Level 21 (Xamarin.Android v5.0 Support))
からAPI Level 21 (Xamarin.Android v5.0 Support)
に変更する(※この変更の意味は、後述のコラムを参照) - Visual Studioを再起動する
- もう一度、図2の[NuGet パッケージの管理]ダイアログを表示し、左側のツリーから[インストール済みのパッケージ]-[すべて]を選択し、中央に表示される「Xamarin.Forms.Maps」の[管理]ボタンを押す。これにより図3のダイロアログが表示されるので、チェックボックスが外れている項目をチェックし直して[OK]ボタンを押すと、先ほどエラーが発生したNuGetパッケージがインストールされる(※これでうまくインストールされない場合は、全てのチェックを外してXamarin.Forms.Mapsをアンインストールして、もう一度インストールし直すとよい)
パッケージのインストールが完了すると、各プロジェクトの参照設定に、次のようなライブラリが追加されているのを確認できる。
【コラム】Xamarin.Forms.Mapsのインストールが失敗する
2015年3月9日現在、エラーが発生する原因は、依存関係から、Androidプロジェクトで必要となるXamarin.Android.Support.v7.AppCompatアセンブリのVersion 21以降が、MonoAndroid,Version=v2.2の条件下でインストールできないためである。Visual Studioでは、[Compile using Android version]がUse Latest Platform (API Level 21 (Xamarin.Android v5.0 Support))
になっていると、MonoAndroid,Version=v2.2となってしまうのである。
そして、これを回避する方法が、先に紹介したAPI Level 21(Xamarin.Android v5.0 Support)
への変更である。
なお、UI上でこの変更を実施すると、プロジェクトを再度読み直すまで、TargetFrameworkVersion(=.csprojファイルで指定されている.NETのターゲットバージョン)の値が正常に処理されない場合がある。手順の中でVisual Studioを再起動したのは、このためである。
4. Xamarin.Forms.Mapsの初期化
Xamarin.Forms.Maps
を使用するためには、プラットフォームごとに、初期化コードを記述する必要がある。
初期化コードは、iOSプロジェクトでは、AppDelegate.csファイルに追加する。
……省略……
namespace MapsSample.iOS {
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate {
public override bool FinishedLaunching(UIApplication app, NSDictionary options) {
global::Xamarin.Forms.Forms.Init();
Xamarin.FormsMaps.Init(); // Xamarin.Forms.Mapsの初期化コード
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
}
|
また、Androidプロジェクトでは、MainActivity.csファイルに追加する。
……省略……
namespace MapsSample.Droid {
[Activity(Label = "MapsSample", Icon = "@drawable/icon", MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : FormsApplicationActivity {
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
Forms.Init(this, bundle);
Xamarin.FormsMaps.Init(this, bundle); // Xamarin.Forms.Mapsの初期化コード
LoadApplication(new App());
}
}
}
|
5. プラットフォームごとの設定(Android)
Xamarin.Forms.Maps
を使用するためには、プラットフォームごとに、もう少し作業が必要である。
Androidでは、次の3つがそれである。
(1)パーミッションの追加
インターネットに接続して地図データをダウンロードするため、INTERNET
、ACCESS_FINE_LOCATION
およびACCESS_NETWORK_STATE
のパーミッションが必要だ。
これらを設定するには、プロジェクトのプロパティで[Android Manifest]を開いて、上記の3つのパーミッションをチェックする。
(2)ヒープの最大サイズの設定
ヒープの最大サイズの指定が無い場合、下記のようにエラーとなりコンパイルが失敗する。
……省略……
1>C:\Users\Seishin\AppData\Local\Xamarin\Android.Support.v7.AppCompat\21.0.3\emb……省略……
1>COMPILETODALVIK : UNEXPECTED TOP-LEVEL error :
========== ビルド: 0 正常終了、1 失敗、1 更新不要、0 スキップ ==========
========== 配置: 0 正常終了、0 失敗、0 スキップ ==========
|
プロジェクトのプロパティで[Android Options]を選択し、[Advanced]タブで[Java Max Heap Size]欄に1G
と設定することで(図7)、この問題を回避できる。
(3)アプリケーションキーの設定
Androidでは、「Google Maps API v2」を使用するため、同サービスのAPIキーが必要になる。APIキーの取得方法については、「Tips:Xamarin.Androidで地図を表示するには?(Google Maps使用)」に解説されているので、そちらを参照していただきたい。
取得したAPIキーを追加するためには、([Properties]の中にある)AndroidManifest.xmlファイルは以下のように修正する。
1
2
3
4
5
6
7
1
9
10
11
|
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example" android:installLocation="auto">
<uses-sdk android:minSdkVersion="15" />
<application>
<meta-data android:name="com.google.android.maps.v2.API_KEY"
android:value="<取得したAPI Keyをここに書く>" />
</application>
</manifest>
|
<manifest>
タグの中の<application>
タグに<meta-data>
タグを追加し、そのandroid:name
属性にはcom.google.android.maps.v2.API_KEY
を、android:value
属性には取得したAPIキーを設定する(1)。
6. プラットフォームごとの設定(iOS)
iOS 7では、現在位置を取得するアプリの場合、起動時に許可を求めるためのメッセージが自動的に表示された。しかしiOS 8では、このような許可を求めるためには、明示的に設定が必要である。
iOSで「位置情報測位の許可」のメッセージを表示するには、Info.plistファイルを(GUIのPListエディターでは設定できないのでテキストエディターで開いて)以下のように修正する。
1
2
3
4
5
1
7
2
9
10
11
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
……省略……
<key>NSLocationAlwaysUsageDescription</key>
<string>Can we use your location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We are using your location</string>
</dict>
</plist>
|
NSLocationAlwaysUsageDescription
キーは「常に許可」時のメッセージであり(1)、NSLocationWhenInUseUsageDescription
キーは「このAppの使用中のみ許可」時のメッセージである(2)。これらのキーを追加すると、アプリ起動時に次のような確認ダイアログが表示される。
7. 地図を表示する(Android/iOS共通のコード)
初期化コードの追加と、プラットフォームごとの設定が完了すると、いよいよ地図の表示が可能である。
地図を表示するためには、App.csファイルを以下のように修正する。
……省略……
using Xamarin.Forms.Maps;
namespace MapsSample {
public class App : Application {
public App() {
MainPage = new MyPage();
}
……省略……
}
public class MyPage : ContentPage {
public MyPage() {
var map = new Map( // <-1
MapSpan.FromCenterAndRadius( // <-2
new Position(35.71, 139.81), // <-3
Distance.FromMiles(0.2))) { // <-4
IsShowingUser = true,
VerticalOptions = LayoutOptions.FillAndExpand
};
Content = new StackLayout {
Children = { map }
};
}
}
}
|
1では、Map
クラスのインスタンスを生成しているが、パラメーターに指定されているのは、MapSpan
クラスのインスタンスである(2)。
MapSpan
オブジェクトは、FromCenterAndRadius
メソッドを使用して生成されており、パラメーターに中心位置の座標(3)*2と縮尺(4)が指定されている。
その他、Map
オブジェクトのIsShowingUser
プロパティ(=現在位置を表示するかどうか)などの設定も行っている。
- *2 設定されている数値は、東京スカイツリーの座標である。
このコードを実行すると、次のような画面になる。
【コラム】Androidのエミュレーターでは実行できない
通常使用しているAndroidエミュレーターでは、Google Play Servicesが含まれていないため、地図を表示することはできない。
Xamarinから提供されているXamarin Android Playerで、同サービスをインストールする手順が、下記のページで紹介されている。
8. まとめ
今回は、Xamarin.Forms.Mapsで地図を表示するまでの一連の作業を解説した。
Xamarin.Forms.Mapsでは、この他にも、マーカーを表示したり、縮尺を操作したりするなどの機能が提供されているが、それらについては次回解説する。
※以下では、本稿の前後を合わせて5回分(第37回~第41回)のみ表示しています。
連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。
37. MvvmCrossのプロジェクトをセットアップするには?
クロスプラットフォーム開発を支援するXamarin用ライブラリの「MvvmCross」を使ってiOS/Androidアプリ開発を行うためのプロジェクトの作成方法を説明する。
38. Xamarin.FormsでListViewコントロールを使用するには?
データの一覧を表示できる「リストビュー」はXamarin.Formsでも提供されている。その基本的な使用方法を解説。また、セルの高さ指定/プログラムによるスクロール/画像表示などの方法も説明する。
39. 【現在、表示中】≫ Xamarin.Formsで地図を表示するには?(Xamarin.Forms.Maps使用)
Android/iOSアプリで各プラットフォーム標準の地図を表示するには、Xamarin.Forms.Mapsコントロールを使う。その基本的な使い方を説明する。
40. Xamarin.Formsで地図の現在位置やピンの表示、縮尺や地図タイプの変更を行うには?(Xamarin.Forms.Maps使用)
Xamarin.Forms.Mapsコントロールで利用可能な機能として、「現在位置」や「衛星写真」「ピン立て」「スライダーコントロールによる地図の拡大・縮小」などを解説する。