Google Play 服务 - 位置 Xamarin Android

Posted

技术标签:

【中文标题】Google Play 服务 - 位置 Xamarin Android【英文标题】:Google Play Services - Location Xamarin Android 【发布时间】:2017-10-25 04:10:23 【问题描述】:

我在我的应用中实现了 Google Play 服务后台位置跟踪。我以前使用过位置管理器,但它在某些设备上不起作用。

使用设备时有很奇怪的事情。由于我已经发布了 GooglePlayServices 大部分设备,包括我的发送位置日志的偏差很大。

有我今天的路图:

数据库中有位置

//...
Latitude    Longitude   Provider    Accuracy
51,0994253  17,1077168  fused   21,5179996490479
51,0994253  17,1077168  fused   21,5179996490479
51,0996427  17,1076683  fused   21,7150001525879
51,0996427  17,1076683  fused   21,7150001525879
51,0996427  17,1076683  fused   21,7150001525879
51,1003416  17,1079516  fused   8
51,1003416  17,1079516  fused   8
51,1003416  17,1079516  fused   8
51,1008037  17,1083013  fused   8
51,1008037  17,1083013  fused   8
51,1008037  17,1083013  fused   8
51,0997649  17,0375168  fused   20               //Strange point
51,0997649  17,0375168  fused   20
51,0997649  17,0375168  fused   20
51,1094489  17,065886   fused   21,1340007781982
51,1094489  17,065886   fused   21,1340007781982
51,1094489  17,065886   fused   21,1340007781982
//....

如您所见,奇怪位置的准确度等于 20,而且看起来非常非常奇怪。

实施:

public class GoogleApiLocationManager : Java.Lang.Object, IResultCallback, ILocationListener

    public GoogleApiLocationManager(Context context, GoogleApiManagerMode requestMode)
        
            _requestMode = requestMode;
            _context = context;
            _client = new GoogleApiClient.Builder(context)
                .AddConnectionCallbacks(OnGoogleConnected)
                .AddOnConnectionFailedListener(OnGoogleConnectFailed)
                .AddApi(LocationServices.API)
                .Build();
            _client.Connect();
        

         public void OnGoogleConnected()
        
            switch (_requestMode)
            
                case GoogleApiManagerMode.LastKnownLocation:
                    SaveLastKnownLocation();
                    break;
                case GoogleApiManagerMode.RequestNewLocation:
                    RunLocationRequest();
                    break;
            
        

        public void OnResult(Java.Lang.Object result)
        
            var locationSettingsResult = (LocationSettingsResult)result;
            try
            
                switch (locationSettingsResult.Status.StatusCode)
                
                    case CommonStatusCodes.Success:
                        LocationServices.FusedLocationApi.RequestLocationUpdates(_client, _locationRequest, this);
                        break;
                    case CommonStatusCodes.ResolutionRequired:
                        Toast.MakeText(_context, "Could not get location. Please enable high accuracy in location settings", ToastLength.Short);
                        var intent = new Intent(Settings.ActionLocationSourceSettings);
                        intent.AddFlags(ActivityFlags.NewTask);
                        _context.StartActivity(intent);
                        break;
                    case LocationSettingsStatusCodes.SettingsChangeUnavailable:
                        //TODO:
                        break;
                
            
            catch (Exception e)
            
                //TODO:
            
        

        private void SaveLastKnownLocation()
        
           //Store to database
           _client.Disconnect();
        

        private void RunLocationRequest()
        
            _locationRequest = CreateLocationRequest();
            var builder = new           
                  LocationSettingsRequest.Builder().AddLocationRequest(_locationRequest);
            var pendingResult = LocationServices.SettingsApi.CheckLocationSettings(_client, builder.Build());
            pendingResult.SetResultCallback(this);
        

         private LocationRequest CreateLocationRequest()
    
        _locationRequest = new LocationRequest();
        _locationRequest.SetInterval((long)_triggerInterval.TotalMilliseconds);
        _locationRequest.SetFastestInterval((long)_triggerInterval.TotalMilliseconds / 2);
        _locationRequest.SetPriority(LocationRequest.PriorityHighAccuracy);

        return _locationRequest;
    

GoogleManager 类每 2 分钟被调用一次,但 AlarmReciever 是 BroadcastReciver 固有的。

[BroadcastReceiver]
public class AlarmReciver : BroadcastReceiver

   //some login to wakeup each 2 minutes...

   //runs google api manager each period
    private void RunLocationManager()
        
            new GoogleApiLocationManager(_context, GoogleApiManagerMode.LastKnownLocation);
            new GoogleApiLocationManager(_context, GoogleApiManagerMode.RequestNewLocation);
        

后台位置跟踪工作正常,但位置日志之间有时存在很大偏差。但是,在使用已弃用的位置管理器时它工作得非常好。

有人遇到过类似的问题吗?

编辑: 我去跑步,我发现每次位置都去同一个地方。这是屏幕:

【问题讨论】:

【参考方案1】:

在定义您的LocationRequest 时,如果您不要求高精度,那么保险丝提供商将使用最低功率选项将位置返回给您。这通常是仅基于 wifi 的位置,其准确度仅与 Google 映射您的位置一样准确。

当然,手机需要开启 wifi、蜂窝和 GPS/定位服务,才能通过融合的提供商提供最佳结果。

AccessFineLocation 添加到您的清单权限并将您的 LocationRequest 优先级设置为高精度,以启动 GPS 并对您的位置进行采样并重新检查您的结果。

LocationRequest _locationRequest = new LocationRequest()
    .SetPriority(LocationRequest.PriorityHighAccuracy);

【讨论】:

感谢您的回复!不幸的是,我已经设置了 PriorityHightAccuracy ;((参见我的编辑)

以上是关于Google Play 服务 - 位置 Xamarin Android的主要内容,如果未能解决你的问题,请参考以下文章

Google Play 服务 - 当前位置

查找位置:Google Play 位置服务或 Android 平台位置 API

查找位置:Google Play 位置服务或 Android 平台位置 API

使用 google play 服务和 FusedLocationProviderClient 进行位置更新

Google Play 服务 - 位置 Xamarin Android

在服务中访问 Google Play 服务位置 API