繁体   English   中英

Xamarin Android通过MvvmCross获取位置

[英]Xamarin Android get location with MvvmCross

我想在我的Xamarin Android应用中实现位置服务。 这是代码:

public class LocationService : ILocationService
{
    private readonly object _lock = new object();

    private static readonly TimeSpan _timeOut = TimeSpan.FromSeconds(20);

    private TaskCompletionSource<MvxCoordinates> _taskSource;

    private readonly IMvxLocationWatcher _locationWatcher;
    private readonly IMvxMainThreadDispatcher _dispatcher;

    public Task<MvxCoordinates> GetCurrentLocation()
    {
        Task<MvxCoordinates> task;
        bool startWatcher = false;

        lock (_lock)
        {
            if (_taskSource == null)
            {
                _taskSource = new TaskCompletionSource<MvxCoordinates>();
                startWatcher = true;
            }
            task = _taskSource.Task;
        }

        if (startWatcher)
        {
            StartWatcher();
        }
        return task;
    }

    public MvxCoordinates GetLastSeenLocation()
    {
        var location = _locationWatcher.LastSeenLocation;
        if (location == null)
        {
            return new MvxCoordinates();
        }
        return new MvxCoordinates()
        {
            Latitude = location.Coordinates.Latitude,
            Longitude = location.Coordinates.Longitude
        };
    }

    public LocationService(IMvxLocationWatcher locationWatcher, IMvxMainThreadDispatcher dispatcher)
    {
        this._locationWatcher = locationWatcher;
        this._dispatcher = dispatcher;

        this._locationWatcher.OnPermissionChanged += PermissionChanged;
    }

    private void StartWatcher()
    {
        Console.WriteLine("StartWatcher");

        _dispatcher.RequestMainThreadAction(() =>
        {
            if (_locationWatcher.Started)
            {
                Console.WriteLine("Watcher already started!");
                return;
            }

            _locationWatcher.Start(new MvxLocationOptions() { Accuracy = MvxLocationAccuracy.Coarse },
                location =>
                {
                    _locationWatcher.Stop();

                    OnSuccess(new MvxCoordinates()
                    {
                        Latitude = location.Coordinates.Latitude,
                        Longitude = location.Coordinates.Longitude
                    });
                },
                error =>
                {
                    _locationWatcher.Stop();
                    Console.WriteLine(error.Code);
                    OnError(new Exception(error.Code.ToString()));
                });

            Task.Delay(_timeOut).ContinueWith(_ => OnTimeout());
        });
    }

    private void OnTimeout()
    {
        Console.WriteLine("Timeout");
        TaskCompletionSource<MvxCoordinates> source;
        lock (_lock)
        {
            source = _taskSource;
            _taskSource = null;
        }
        source?.SetException(new Exception(MvxLocationErrorCode.Timeout.ToString()));

        if (_locationWatcher.Started)
        {
            _locationWatcher.Stop();
        }
    }

    private void OnSuccess(MvxCoordinates coordinates)
    {
        Console.WriteLine("Updated: {0}, {1}", coordinates.Longitude.ToString(), coordinates.Latitude.ToString());
        TaskCompletionSource<MvxCoordinates> source;
        lock (_lock)
        {
            source = _taskSource;
            _taskSource = null;
        }
        source?.SetResult(coordinates);
    }

    private void OnError(Exception error)
    {
        Console.WriteLine("Error: {0}", error.Message);
        TaskCompletionSource<MvxCoordinates> source;
        lock (_lock)
        {
            source = _taskSource;
            _taskSource = null;
        }
        source?.SetException(error);
    }

    private void PermissionChanged(object sender, MvxValueEventArgs<MvxLocationPermission> e)
    {
        Console.WriteLine("Permission changed: " + e.Value.ToString());
        if (e.Value != MvxLocationPermission.Denied)
        {
            return;
        }

        TaskCompletionSource<MvxCoordinates> source;
        lock (_lock)
        {
            source = _taskSource;
            _taskSource = null;
        }
        source?.SetException(new Exception(MvxLocationErrorCode.PermissionDenied.ToString()));
    }
}

但是我有这个输出:

[0:] mvx:警告:41.12位置服务提供者不可用-返回null 03-05 12:52:08.449 I / mvx(4065):41.12位置服务提供者不可用-返回null ServiceUnavailable 03-05 12:52:08.457 I / mono-stdout(4065):服务不可用

我在模拟器和真实设备上都有这个。 怎么了?

我找到了解决方案。

在Android清单中未检查ACCESS_FINE_LOCATION

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM