コメント
コメントの投稿
※名前とタイトルが入力されていないコメントでは他のコメントとの区別ができません。
入力されていないコメントには返信しませんのであらかじめご了承くださいませ。
namespace AppName.ViewModels
{
/// <summary>
/// 位置情報格納クラス
/// </summary>
[System.Diagnostics.DebuggerStepThrough()]
public class GeoCoordinate
{
/// <summary>
/// 緯度
/// </summary>
public double Latitude { get; set; }
/// <summary>
/// 経度
/// </summary>
public double Longitude { get; set; }
/// <summary>
/// 高度
/// </summary>
public double Altitude { get; set; }
/// <summary>
/// 取得時間
/// </summary>
public DateTimeOffset Timestamp { get; set; }
}
}
using System.Threading.Tasks;
using AppName.ViewModels;
namespace AppName.Services
{
public delegate void OnLocationChangedDelegate(GeoCoordinate location);
public delegate void OnLocationErrorDelegate(string error);
//DependencyServiceから利用する
public interface ILocationService
{
// GPS初期化処理
void Initialize();
//現在の位置情報取得(非同期)
Task<GeoCoordinate> GetGeoCoordinateAsync(int timeout);
// 非同期で位置情報の変更をリスニングする
void StartListening(int minTime, double minDistance, bool includeHeading = false);
//位置情報変更イベント
event OnLocationChangedDelegate OnLocationChanged;
event OnLocationErrorDelegate OnLocationError;
}
}
<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_BACKGROUND_LOCATION" />
<uses-feature android:name="android.hardware.location.gps"
android:required="false" />
<uses-feature android:name="android.hardware.location.network"
android:required="false" />
<!-- ForegroundServiceを実装している場合 -->
<service android:name="MyForeGroundService"
android:foregroundServiceType="location" >
</service>
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
using AppName.Droid.Services;
using AppName.Services;
using AppName.ViewModels;
using Plugin.Geolocator;
using Plugin.Geolocator.Abstractions;
[assembly: Dependency(typeof(LocationService))]
namespace AppName.Droid.Services
{
public class LocationService : ILocationService
{
private IGeolocator _locator = null;
/// <summary>
/// GPSを初期化する
/// </summary>
public void Initialize()
{
_locator = CrossGeolocator.Current;
_locator.DesiredAccuracy = 30; //30mの精度に指定
}
/// <summary>
/// 非同期で現在座標を取得する
/// </summary>
/// <param name="timeout">タイムアウト時間</param>
/// <returns>現在の座標</returns>
public async Task<GeoCoordinate> GetGeoCoordinateAsync(int timeout)
{
//指定した秒数までを限度に現在の位置を取得する
Position position = await _locator.GetPositionAsync(timeoutMilliseconds: timeout);
return this.ConvertGeoCoordinate(position);
}
/// <summary>
/// Plugin.Geolocator.Abstractions.Position を GeoCoordinate に変換し値を返す
/// </summary>
/// <param name="position">Plugin.Geolocator.Abstractions.Position</param>
/// <returns>GeoCoordinate</returns>
private GeoCoordinate ConvertGeoCoordinate(Position position)
{
var result = new GeoCoordinate
{
Latitude = position.Latitude, //緯度
Longitude = position.Longitude, //経度
Altitude = position.Altitude, //高度
Timestamp = position.Timestamp //取得時間
};
return result;
}
/// <summary>
/// 非同期で位置情報の変更をリスニングする
/// </summary>
/// <param name="minTime"></param>
/// <param name="minDistance"></param>
/// <param name="includeHeading"></param>
public void StartListening(int minTime, double minDistance, bool includeHeading = false)
{
if (_locator != null &&
_locator.IsGeolocationEnabled &&
_locator.IsGeolocationAvailable)
{
_locator.AllowsBackgroundUpdates = true;
_locator.StartListeningAsync(minTime, minDistance, includeHeading);
//位置変更時イベント
_locator.PositionChanged += (sender, e) =>
{
if (this.OnLocationChanged != null)
{
this.OnLocationChanged(this.ConvertGeoCoordinate(e.Position));
}
};
//位置取得エラー時イベント
_locator.PositionError += (sender, e) =>
{
if (this.OnLocationError != null)
{
this.OnLocationError(e.Error.ToString());
}
};
}
}
//位置情報変更イベント
public event OnLocationChangedDelegate OnLocationChanged;
public event OnLocationErrorDelegate OnLocationError;
}
}
<key>NSLocationAlwaysUsageDescription</key>
<string>位置情報を使用します。</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>位置情報を使用します。</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>位置情報を使用します。</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
using AppName.iOS.Services;
using AppName.Services;
using AppName.ViewModels;
using Plugin.Geolocator;
using Plugin.Geolocator.Abstractions;
[assembly: Dependency(typeof(LocationService))]
namespace AppName.iOS.Services
{
public class LocationService : ILocationService
{
private IGeolocator _locator = null;
/// <summary>
/// GPSを初期化する
/// </summary>
public void Initialize()
{
_locator = CrossGeolocator.Current;
_locator.DesiredAccuracy = 30; //30mの精度に指定
if (CLLocationManager.Status != CLAuthorizationStatus.AuthorizedAlways)
{
this.RequestPermision();
}
}
void RequestPermision()
{
CLLocationManager manager = new CLLocationManager();
// iOS 8 has additional permissions requirements
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
manager.RequestAlwaysAuthorization();
}
}
/// <summary>
/// 非同期で現在座標を取得する
/// </summary>
/// <param name="timeout">タイムアウト時間</param>
/// <returns>現在の座標</returns>
public async Task<GeoCoordinate> GetGeoCoordinateAsync(int timeout)
{
//指定した秒数までを限度に現在の位置を取得する
Position position = await _locator.GetPositionAsync(timeoutMilliseconds: timeout);
return this.ConvertGeoCoordinate(position);
}
/// <summary>
/// Plugin.Geolocator.Abstractions.Position を GeoCoordinate に変換し値を返す
/// </summary>
/// <param name="position">Plugin.Geolocator.Abstractions.Position</param>
/// <returns>GeoCoordinate</returns>
private GeoCoordinate ConvertGeoCoordinate(Position position)
{
var result = new GeoCoordinate
{
Latitude = position.Latitude, //緯度
Longitude = position.Longitude, //経度
Altitude = position.Altitude, //高度
Timestamp = position.Timestamp //取得時間
};
return result;
}
/// <summary>
/// 非同期で位置情報の変更をリスニングする
/// </summary>
/// <param name="minTime"></param>
/// <param name="minDistance"></param>
/// <param name="includeHeading"></param>
public void StartListening(int minTime, double minDistance, bool includeHeading = false)
{
if (_locator != null &&
_locator.IsGeolocationEnabled &&
_locator.IsGeolocationAvailable)
{
_locator.AllowsBackgroundUpdates = true;
_locator.StartListeningAsync(minTime, minDistance, includeHeading);
//位置変更時イベント
_locator.PositionChanged += (sender, e) =>
{
if (this.OnLocationChanged != null)
{
this.OnLocationChanged(this.ConvertGeoCoordinate(e.Position));
}
};
//位置取得エラー時イベント
_locator.PositionError += (sender, e) =>
{
if (this.OnLocationError != null)
{
this.OnLocationError(e.Error.ToString());
}
};
}
}
//位置情報変更イベント
public event OnLocationChangedDelegate OnLocationChanged;
public event OnLocationErrorDelegate OnLocationError;
}
}
using AppName.Services;
using Xamarin.Forms;
public class TestPage : ContentPage
{
void OnEnableGpsClick()
{
//GPSデバイスを初期化する
DependencyService.Get<ILocationService>().Initialize();
//10秒までを限度に現在の位置を取得する
DependencyService.Get<ILocationService>().GetGeoCoordinateAsync(10000);
//DependencyServiceの位置変更イベントと紐づける
DependencyService.Get<ILocationService>().OnLocationChanged += new OnLocationChangedDelegate(this.LocationChanged);
DependencyService.Get<ILocationService>().OnLocationError += new OnLocationErrorDelegate(this.LocationError);
//非同期スレッドを開始する
DependencyService.Get<ILocationService>().StartListening(10, 10, true);
}
//現在位置が変更されたら通知する
private void LocationChanged(GeoCoordinate location)
{
DependencyService.Get<INotificationService>().SetNotifyCondition(DateTimeOffset.Now, 0, "");
DependencyService.Get<INotificationService>().On("位置変更", "LocationUtility", "緯度:" + location.Latitude.ToString() + " 経度:" + location.Longitude + " 高度:" + location.Altitude);
}
//現在位置の取得エラーがあった場合、通知する
private void LocationError(string error)
{
DependencyService.Get<INotificationService>().SetNotifyCondition(DateTimeOffset.Now, 0, "");
DependencyService.Get<INotificationService>().On("LocationUtility", "位置取得エラー", error);
}
}
※名前とタイトルが入力されていないコメントでは他のコメントとの区別ができません。
入力されていないコメントには返信しませんのであらかじめご了承くださいませ。