😽

Xamarin.Forms (Android) で Map を使って現在地を取得し、ピンを追加する

2022/05/11に公開

はじめに

以下のものを準備

  • Visual Studio 2022
  • Google アカウント

Notification Hubs の時 と同様、Android のエミュレータを使用で進めることにした。

全体像

Xamarin.Androidで地図を使う際、Xamarin.Forms.Map をコントローラとして制御を行い、地図自体は Google Map の API を使って表示する事になるみたい(おそらく)。

実装

  1. マップの追加
  2. ボタンを押して現在地を取得
  3. マップ上にピンを追加

マップの追加

こちらの公式Docsを参考に進める。https://docs.microsoft.com/ja-jp/xamarin/xamarin-forms/user-interface/map/setup

Nu Get

共有プロジェクトを右クリックして、全プロジェクトにインストール

  • Xamarin.Forms.Maps (ver. 5.0.0.2196)

MainAvctivity.csに追加

Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
Xamarin.FormsMaps.Init(this, savedInstanceState); // ← この行を追加
LoadApplication(new App());

Google Map API キーを取得

こちらの公式Docsを参考に進めていく。https://docs.microsoft.com/ja-jp/xamarin/android/platform/maps-and-location/maps/obtaining-a-google-maps-api-key?tabs=windows

AndroidManifest.xml の に以下を追加

<application> ブロック内に以下を追加

<meta-data android:name="com.google.android.geo.API_KEY" android:value="PASTE-YOUR-API-KEY-HERE" />
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<uses-library android:name="org.apache.http.legacy" android:required="false" />

以下の <uses-permission> も追加

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

MainPage.xaml を以下のように修正

<maps:Map x:Name="map>を挿入して起動することで地図が見えるようになる。xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"を追加しておくことも忘れてはいけない。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
             x:Class="PushDemoAndroid.MainPage">

    <StackLayout>
        <Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
            <Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/>
        </Frame>
        <maps:Map x:Name="map" />
    </StackLayout>

</ContentPage>

ボタンを押して現在地を取得

上のコードの中で、 <Button Text="現在地周辺を検索" HorizontalOptions="Start" Clicked="CurrentLocationButton_Clicked"/> のボタンを押すと、<CurrentLocationButton_Clicked>の関数が呼び出されるようにしている。

MainPage.xaml にボタンを追加

<StackLayout> ブロックの中に以下を追記する。

<Button Text="現在地周辺を検索"  HorizontalOptions="Start" Clicked="CurrentLocationButton_Clicked"/>
        <Label x:Name="GPSlabel" HorizontalOptions="Center" TextColor="Black"/>

MainPage.xaml.cs にて関数を宣言

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Essentials;
using Xamarin.Forms.Maps;
…
private async void CurrentLocationButton_Clicked(object sender, EventArgs e)
{
    try
    {
        var request = new GeolocationRequest(GeolocationAccuracy.Medium);
        var location = await Geolocation.GetLocationAsync(request);

        if (location != null)
        {
            GPSlabel.Text = $"{location.Latitude},{location.Longitude}";
            // enable IsShowingUser (built-in button to get the current location)
            map.IsShowingUser = true;
            // move the map to current location
            Position position = new Position(Convert.ToDouble(location.Latitude), Convert.ToDouble(location.Longitude));
            MapSpan mapSpan = new MapSpan(position, 0.01, 0.01);
            map.MoveToRegion(mapSpan);
        }
    }
    catch (Exception)
    {

    }
}

アプリを起動すると、「現在地の取得許可」というポップアップが出るので、確認して許可する。その後、<Label x:Name="GPSlabel" HorizontalOptions="Center" TextColor="Black"/>に緯度経度が画面上で反映され、現在地に画面が移動することを確認できる。もしも、エミュレータを使用していれば、現在地は Googleplex にセットされているはずだ。

マップ上にピンを追加

MainPage.xaml.csの中のmap.MoveToRegion(mapSpan);の後に、以下を追加

map.MoveToRegion(mapSpan);
// Add Pin
AddPin();

MainPage.xaml.cs にて関数を実装

今回はピンを立てれるかどうかのお試しなので、ピンを立てる際に必要な情報を関数内で設定しているが、当たり前だがこのあたりの情報は引数渡しが望ましい。

private void AddPin()
{
    Pin pin = new Pin
    {
        Label = "Santa Cruz",
        Address = "The city with a boardwalk",
        Type = PinType.Place,
        Position = new Position(37.42056167283825, -122.08411115979173)
    };
    map.Pins.Add(pin);
}

追加した後にアプリを実行すると、指定した場所にピンが立っていることが確認できる。追加したピンはmap.clear()により削除することができる。デモ動画は次号にて、まとめて掲載する予定。
ちなみに、もし、ピンのデザインを工夫したいのであれば、こちら の公式Docsも参考になるかと思うが、今回は割愛。

GitHubで編集を提案

Discussion