使用gps定位系统服务依赖注入

时间:2015-04-22 15:37:45

标签: c# android ios mobile xamarin

我希望使用Xamarin的依赖注入获取平台特定的位置详细信息,但遇到问题。更有可能做错了。

这是我目前的设置:

nuMaps /接口/ ILocationService.cs

using Xamarin.Forms.Maps;

namespace nuMaps
{
    public interface ILocationService
    {
        void initLocationService();
        Position getCurrentPosition();
    }
}

nuMaps / nuMaps.Droid /接口/ 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 /查看/ 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();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

我认为问题出在ILocationService的实施中。

我会删除实施活动(您为什么要使用OnCreate?)并查看http://developer.xamarin.com/guides/android/platform_features/maps_and_location/location/

我建议Android通过google play apis获取GPS位置,这需要实施ILocationListenerIGoogleApiClientConnectionCallbacksIGoogleApiClientOnConnectionFailedListener。希望有所帮助!

编辑评论:

如果问题中的LocationService是最新的,我不会发现您正在实施IGoogleApiClientConnectionCallbacksILocationListener。可能是因为mappage正在使用gps,GetLastKnownLocation有效,因为最近获得了一个位置。

GPS位置请求是异步操作 - IGoogleApiClientConnectionCallbacks的方法之一是OnConnected,您应该在其中调用类似的内容:

LocationServices.FusedLocationApi.RequestLocationUpdates(googleApiClient, locationRequest, this);

这将主动请求位置更新,然后在返回位置更新时触发OnLocationChanged(Location location)。这都是异步的,因此您可能需要在LocationService中公开这些事件并订阅它们。

答案 1 :(得分:0)

您可以尝试TinyIoC而不是Xamarin依赖服务。它适用于特定于平台的实现,例如位置服务。

也许Xamarin依赖服务可以用于这些类型的事情,但到目前为止我只用于自定义渲染器。对于更多基于服务的东西,我使用TinyIoC。