使用 gps 定位系统服务依赖注入
Using gps location system services dependency injection
我希望使用 Xamarin 的依赖项注入获取特定于平台的位置详细信息,但 运行 问题。很可能是因为做错了。
这是我当前的设置:
nuMaps/Interfaces/ILocationService.cs
using Xamarin.Forms.Maps;
namespace nuMaps
{
public interface ILocationService
{
void initLocationService();
Position getCurrentPosition();
}
}
nuMaps/nuMaps.Droid/Interfaces/LocationService.cs
using System;
using nuMaps;
using nuMaps.Droid;
using Xamarin.Forms.Maps;
using Android.App;
using Android.Gms.Common;
using Android.Gms.Common.Apis;
using Android.Gms.Location;
using Android.Locations;
using Android.Widget;
[assembly: Xamarin.Forms.Dependency (typeof (LocationService))]
namespace nuMaps.Droid
{
public class LocationService : Java.Lang.Object, ILocationService, IGoogleApiClientConnectionCallbacks, IGoogleApiClientOnConnectionFailedListener, Android.Gms.Location.ILocationListener
{
readonly IGoogleApiClient _googleApiClient;
readonly LocationRequest _locRequest;
Position _currentPosition;
Location _currentLocation;
public LocationService()
{
Console.WriteLine ("LocationService constructor");
_currentPosition = new Position (0, 0);
_googleApiClient = new GoogleApiClientBuilder (Xamarin.Forms.Forms.Context)
.AddApi (LocationServices.Api)
.AddConnectionCallbacks (this)
.AddOnConnectionFailedListener (this)
.Build ();
_locRequest = new LocationRequest ();
}
#region ILocationService implementation
public void initLocationService()
{
_googleApiClient.Connect ();
}
public Position getCurrentPosition ()
{
if (_googleApiClient.IsConnected) {
_currentLocation = LocationServices.FusedLocationApi.GetLastLocation (_googleApiClient);
_currentPosition = new Position (_currentLocation.Latitude, _currentLocation.Longitude);
}
_googleApiClient.Disconnect ();
return new Position (_currentLocation.Latitude, _currentLocation.Longitude);
}
#endregion
public void OnLocationChanged(Location l)
{
Console.WriteLine ("OnLocationChanged");
_currentLocation = l;
}
public void OnConnectionFailed (ConnectionResult result)
{
Console.WriteLine ("ConnectionFailed");
}
#region IGoogleApiClientConnectionCallbacks implementation
public void OnConnected (Android.OS.Bundle connectionHint)
{
Console.WriteLine ("OnConnected");
if (!_googleApiClient.IsConnected)
LocationServices.FusedLocationApi.RequestLocationUpdates (_googleApiClient, _locRequest, this);
_currentLocation = LocationServices.FusedLocationApi.GetLastLocation (_googleApiClient);
}
public void OnConnectionSuspended (int cause)
{
Console.WriteLine ("OnConnectionSuspended");
}
#endregion
}
}
nuMaps/Views/MapPage.xaml.cs
中的用法
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using System;
using System.Diagnostics;
namespace nuMaps
{
public partial class MapPage : ContentPage
{
public MapPage ()
{
InitializeComponent ();
Position p = DependencyService.Get<ILocationService>().getCurrentPosition();
MyMap.MoveToRegion (
MapSpan.FromCenterAndRadius (
p, Distance.FromMiles (1)
)
);
}
}
}
nuMaps/Views/Loginpage.xaml.cs
using System;
using Xamarin.Forms;
using nuMaps;
namespace nuMaps
{
public partial class LoginPage : ContentPage
{
public LoginPage ()
{
InitializeComponent ();
/*
* Init platform specific location service.
* TODO: This *shouldn't* need to happen, but we don't get location information until
* the OnConnected callback happens which is too slow to put in getCurrentLocation method.
*/
DependencyService.Get<ILocationService>().initLocationService();
}
}
}
我认为问题出在您对 ILocationService
的实施中。
我会删除实现 activity(您为什么要使用 OnCreate?)并查看 http://developer.xamarin.com/guides/android/platform_features/maps_and_location/location/。
我建议 Android 通过 google play api 获取 GPS 位置,这将需要实施 ILocationListener
、IGoogleApiClientConnectionCallbacks
和 IGoogleApiClientOnConnectionFailedListener
.希望对您有所帮助!
编辑评论:
如果问题中的 LocationService 是最新的,我看不到您正在实施 IGoogleApiClientConnectionCallbacks
或 ILocationListener
。可能是因为地图页面使用了gps,所以GetLastKnownLocation
可以,因为最近获取了一个位置。
GPS 位置请求是一个异步操作 - IGoogleApiClientConnectionCallbacks
的方法之一是 OnConnected,您应该调用类似的方法:
LocationServices.FusedLocationApi.RequestLocationUpdates(googleApiClient, locationRequest, this);
这将主动请求位置更新,然后在返回位置更新时触发 OnLocationChanged(Location location)
。这都是异步的,因此您可能需要在 LocationService 中公开这些事件并订阅它们。
您可以尝试 TinyIoC 而不是 Xamarin 依赖服务。它适用于特定于平台的实现,例如定位服务。
也许 Xamarin Dependency Service 可以用于这些类型的事情,但到目前为止我只将它用于自定义渲染器。对于更多基于服务的东西,我使用 TinyIoC。
我希望使用 Xamarin 的依赖项注入获取特定于平台的位置详细信息,但 运行 问题。很可能是因为做错了。
这是我当前的设置:
nuMaps/Interfaces/ILocationService.cs
using Xamarin.Forms.Maps;
namespace nuMaps
{
public interface ILocationService
{
void initLocationService();
Position getCurrentPosition();
}
}
nuMaps/nuMaps.Droid/Interfaces/LocationService.cs
using System;
using nuMaps;
using nuMaps.Droid;
using Xamarin.Forms.Maps;
using Android.App;
using Android.Gms.Common;
using Android.Gms.Common.Apis;
using Android.Gms.Location;
using Android.Locations;
using Android.Widget;
[assembly: Xamarin.Forms.Dependency (typeof (LocationService))]
namespace nuMaps.Droid
{
public class LocationService : Java.Lang.Object, ILocationService, IGoogleApiClientConnectionCallbacks, IGoogleApiClientOnConnectionFailedListener, Android.Gms.Location.ILocationListener
{
readonly IGoogleApiClient _googleApiClient;
readonly LocationRequest _locRequest;
Position _currentPosition;
Location _currentLocation;
public LocationService()
{
Console.WriteLine ("LocationService constructor");
_currentPosition = new Position (0, 0);
_googleApiClient = new GoogleApiClientBuilder (Xamarin.Forms.Forms.Context)
.AddApi (LocationServices.Api)
.AddConnectionCallbacks (this)
.AddOnConnectionFailedListener (this)
.Build ();
_locRequest = new LocationRequest ();
}
#region ILocationService implementation
public void initLocationService()
{
_googleApiClient.Connect ();
}
public Position getCurrentPosition ()
{
if (_googleApiClient.IsConnected) {
_currentLocation = LocationServices.FusedLocationApi.GetLastLocation (_googleApiClient);
_currentPosition = new Position (_currentLocation.Latitude, _currentLocation.Longitude);
}
_googleApiClient.Disconnect ();
return new Position (_currentLocation.Latitude, _currentLocation.Longitude);
}
#endregion
public void OnLocationChanged(Location l)
{
Console.WriteLine ("OnLocationChanged");
_currentLocation = l;
}
public void OnConnectionFailed (ConnectionResult result)
{
Console.WriteLine ("ConnectionFailed");
}
#region IGoogleApiClientConnectionCallbacks implementation
public void OnConnected (Android.OS.Bundle connectionHint)
{
Console.WriteLine ("OnConnected");
if (!_googleApiClient.IsConnected)
LocationServices.FusedLocationApi.RequestLocationUpdates (_googleApiClient, _locRequest, this);
_currentLocation = LocationServices.FusedLocationApi.GetLastLocation (_googleApiClient);
}
public void OnConnectionSuspended (int cause)
{
Console.WriteLine ("OnConnectionSuspended");
}
#endregion
}
}
nuMaps/Views/MapPage.xaml.cs
中的用法using Xamarin.Forms;
using Xamarin.Forms.Maps;
using System;
using System.Diagnostics;
namespace nuMaps
{
public partial class MapPage : ContentPage
{
public MapPage ()
{
InitializeComponent ();
Position p = DependencyService.Get<ILocationService>().getCurrentPosition();
MyMap.MoveToRegion (
MapSpan.FromCenterAndRadius (
p, Distance.FromMiles (1)
)
);
}
}
}
nuMaps/Views/Loginpage.xaml.cs
using System;
using Xamarin.Forms;
using nuMaps;
namespace nuMaps
{
public partial class LoginPage : ContentPage
{
public LoginPage ()
{
InitializeComponent ();
/*
* Init platform specific location service.
* TODO: This *shouldn't* need to happen, but we don't get location information until
* the OnConnected callback happens which is too slow to put in getCurrentLocation method.
*/
DependencyService.Get<ILocationService>().initLocationService();
}
}
}
我认为问题出在您对 ILocationService
的实施中。
我会删除实现 activity(您为什么要使用 OnCreate?)并查看 http://developer.xamarin.com/guides/android/platform_features/maps_and_location/location/。
我建议 Android 通过 google play api 获取 GPS 位置,这将需要实施 ILocationListener
、IGoogleApiClientConnectionCallbacks
和 IGoogleApiClientOnConnectionFailedListener
.希望对您有所帮助!
编辑评论:
如果问题中的 LocationService 是最新的,我看不到您正在实施 IGoogleApiClientConnectionCallbacks
或 ILocationListener
。可能是因为地图页面使用了gps,所以GetLastKnownLocation
可以,因为最近获取了一个位置。
GPS 位置请求是一个异步操作 - IGoogleApiClientConnectionCallbacks
的方法之一是 OnConnected,您应该调用类似的方法:
LocationServices.FusedLocationApi.RequestLocationUpdates(googleApiClient, locationRequest, this);
这将主动请求位置更新,然后在返回位置更新时触发 OnLocationChanged(Location location)
。这都是异步的,因此您可能需要在 LocationService 中公开这些事件并订阅它们。
您可以尝试 TinyIoC 而不是 Xamarin 依赖服务。它适用于特定于平台的实现,例如定位服务。
也许 Xamarin Dependency Service 可以用于这些类型的事情,但到目前为止我只将它用于自定义渲染器。对于更多基于服务的东西,我使用 TinyIoC。