zoukankan      html  css  js  c++  java
  • [译]:Xamarin.Android平台功能——位置服务

    返回索引目录
    原文链接:Location Services.
    译文链接:Xamarin.Android平台功能——位置服务
    本部分介绍位置服务以及与如何使用位置提供商服务

    Location Services

    本教程将介绍如何在Android应用中定位,以及如何利用Android Location Service API来获取用户位置,同时还会通过Google Location Services API的位置服务来处理定位。

    概述

    Android提供多种定位技术接口,如利用蜂窝塔、WiFi和GPS。针对每一个定位技术的细节都已经被抽象为 location providers ,这使得应用可以通过一致的方法来获取位置,而不用关心具体的服务实现。在本教程中,我们将介绍Android Location Service API,以及如何利用LocationManager来与系统位置服务进行通信。在教程的第二部分,我们会利用Google Location Services API —— 可用通过Google Play服务整合的定位功能来动态切换定位提供技术。

    定位基础

    在Android中,无论你使用什么API来获取定位数据,其中的基本概念是一致的。在本节中,我们将介绍位置提供程序和与位置相关的权限。

    位置提供程序

    有多种内置技术来精准定位用户位置。要用到哪些硬件取决于选择哪种类型的location provider来收集数据。Android中有以下三种位置提供程序:

    • GPS Provider —— GPS定位最为精准,但耗电最多,且在室外定位最好。此提供程序组合使用GPS和辅助GPS(aGPS) —— 由蜂窝塔收集GPS数据并返回。
    • Network Provider —— 提供程序组合使用WiFi和蜂窝数据,包括由蜂窝塔收集的aGPS数据。它耗电要比GPS Provider要少,但是它的定位精度会有所偏差。
    • Passive Provider —— 使用由其他应用或服务生成的定位数据。这个数据不太可靠,但相对节能,在不需要经常更新位置信息的应用中是一个比较理想的方案。

    位置提供程序并不是总是可用。例如,你可能需要在应用中使用GPS,但是GPS在设置中是关闭状态,或者设备没有GPS模块支持。如果特定的提供程序不可用,选择使用它会返回null值。

    位置权限

    一个定位应用需要访问设备的硬件传感器,以便于接收GPS,WiFi和蜂窝数据。访问权限由应用的Android Manifest控制。其中涉及到了两个权限 —— 这取决于你的应用要求和选择了哪个API,你可以申请其中一个权限:

    • ACCESS_FINE_LOCATION —— 允许应用访问GPS。在使用GPS Provider和Passive Provider选项时必需 —— Passive Provider要有访问其他应用或服务收集的GPS数据的权限。在Netword Provider中,此权限可选。
    • ACCESS_COARSE_LOCATION —— 允许应用访问蜂窝或WiFi位置信息。在使用Network Provider时,如果没有设置ACCESS_FINE_LOCATION,则此选项必需。

    在目标为API版本为21(Android 5.0 Lollipop)或者更高版本中,应用可以在没有GPS硬件模块的设备上使用ACCESS_FINE_LOCATION权限。如果你的应用需要GPS硬件,你需要在Android Manifest中明确添加android.hardware.location.gps uses-feature元素。更多信息见:uses-feature element

    要设置权限,在解决方案管理器中,双击Properties,然后切换到Android Manifest标签。Required Permissions部分为权限列表:

    注:图为官方文档内的图,上面的描述为Visual Studio操作描述。

    设置这些权限会告诉Android,你的应用需要访问那个定位技术的位置提供程序。

    注意:设置了ACCESS_FINE_LOCATION意味着包括了两个定位数据权限。你不需要同时设置两个权限,仅仅为你的应用设置最少要求的权限。

    使用Android Location Service获取位置信息

    原文示例代码译文示例代码

    Android位置服务是Android中使用位置信息的标准API。位置数据是由硬件传感器收集,并通过系统服务集中处理 —— 系统服务可以在应用中使用LocationManager类和ILocationListener来访问。

    为了通过Android位置服务获取用户位置,我们需要以下操作:

    1. 添加对LocationManager类的引用
    2. 使用LocationManager向特定的服务程序请求位置更新
    3. 实现ILocationListener接口,并在其中处理位置改变事件。
    4. 当应用进入后台时,停止位置更新。

    位置服务

    位置服务是系统中服务管理的一种特殊类型。系统服务和硬件设备交互,并一直保持运行。要在 我们的应用中使用位置更新,我们需要利用LocationManager和RequestLocationUpdates调用向系统位置服务请求位置更新。

    位置管理

    我们可以通过LocationManager类实例来访问系统位置服务。LocationManager是一个特殊的类,它用于和系统位置服务交互,并通过它调用方法。应用可以通过调用GetSystemService来引用LocationManager,同时需要传入一个服务类型,示例如下:

    LocationManager locMgr;
    ...
    locMgr = GetSystemService (Context.LocationService) as LocationManager;
    

    OnCreate中比较适合创建LocationManager引用。将LocationManager定义为类的变量会比较好,这样在Activity的生命周期中的各个点都可以调用它。

    请求位置更新

    一旦我们的应用创建了LocationManager引用,我们就需要告诉LocationManager我们需要什么类型的位置信息,以及我们要多久更新一次。我们可以通过调用LocationManager类对象的RequestionLocationUpdates方法(同时需要传递更新条件)来更新位置信息。

    RequestionLocationUpdates方法告诉系统位置服务,你的应用需要开始接收位置更新。此方法语句你指定提供程序,以及控制更新频率的时间和距离阈值。例如,如下代码,要求每2000毫秒请求一次位置更新,并且只有当位置更改超过1米时才更新:

    protected override void OnResume ()
    {
        base.OnResume ();
        string Provider = LocationManager.GpsProvider;
    
        if(locMgr.IsProviderEnabled(Provider))
        {
        locMgr.RequestLocationUpdates (Provider, 2000, 1, this);
        }
        else
        {
        Log.Info(tag, Provider + " is not available. Does the device have location services enabled?");
        }
    }
    

    应用程序应该按照需要控制执行请求位置更新。这可以延长电池寿命,同时为用户提供更好的体验。

    订阅位置更新

    一旦应用通过LocationManager请求了位置更新,它可以通过实现ILocationListener接口来接受服务提供的信息。此接口提供监控位置服务和位置提供程序的方法。

    以下代码示例为在MainActivity中实现ILocationListener:

    public class MainActivity : Activity, ILocationListener
    {
        ...
    
        public void OnProviderEnabled (string provider)
        {
            ...
        }
        public void OnProviderDisabled (string provider)
        {
            ...
        }
        public void OnStatusChanged (string provider, Availability status, Bundle extras)
        {
            ...
        }
        public void OnLocationChanged (Android.Locations.Location location)
        {
            ...
        }
    }
    

    此接口让我们可以订阅四个系统事件,以供检测提供程序状态和获取位置信息:

    • OnProviderEnabled和OnProviderDisabled —— 互补方法,当用户启用或禁用提供程序时通知。(例如:用户可能禁用GPS来省电)。
    • OnStatusChanged —— 当提供程序可用性发生改变时通知,同时还提供相应的状态。(例如:当用户进入室内时,GPS的可用性可能会发生改变)
    • OnLocationChanged —— 当用户位置改变情况满足我们设置的更新条件时,系统调用OnLocationChanged。

    以下代码示例说明了Activity应该如何实现OnLocationChanged方法来接收位置更新,并将其显示到界面:

    TextView latitude;
    TextView longitude;
    
    public void OnLocationChanged (Location location)
    {
    latitude.Text = "Latitude: " + location.Latitude;
    longitude.Text = "Longitude: " + location.Longitude;
    }
    

    停止位置更新

    RemoveUpdates方法告诉系统位置服务停止发送更新数据到我们的应用。在OnPause中调用此方法,当应用的Activity不在前台显示时,应用移除位置更新可以节省电量:

    protected override void OnPause ()
    {
    base.OnPause ();
    locMgr.RemoveUpdates (this);
    }

    如果你的应用需要在后台仍可已获取位置更新,你需要创建一个定制服务来订阅系统位置服务。关于后台服务的信息见:原文:Backgrounding with Android Services

    获取最好的提供程序

    上述示例使用GPS作为位置提供程序。但是,GPS并不是所有情况下都可用,例如,设备处于室内或设备没有GPS接收器。如果是这种情况,我们会从提供程序获得null值。

    如果我们想要我们的应用在GPS不可用的情况下工作,我们可以应用启动时使用GetBestProvider方法获取最好且可用(设备支持且用户启用)的位置提供程序。我们可以通过告诉GetBestProvider方法我们的提供程序要求来取代直接传递指定的提供程序。例如:传入精度和耗电要求 —— 使用Criteria对象,这样GetBestProvider会通过给定的Criteria来返回最适合的提供程序。

    以下代码展示了如何获得最合适的提供程序,以及在请求位置更新时,如何使用它:

    Criteria locationCriteria = new Criteria();
    
    locationCriteria.Accuracy = Accuracy.Coarse;
    locationCriteria.PowerRequirement = Power.Medium;
    
    locationProvider = locMgr.GetBestProvider(locationCriteria, true);
    
    if(locationProvider != null)
    {
        locMgr.RequestLocationUpdates (locationProvider, 2000, 1, this);
    }
    else
    {
        Log.Info(tag, "No location providers available");
    }
    

    注意:如果用户禁用了所有位置提供程序,GetBestProvider将会返回null值。

    为了展示代码如何在真实设备上工作,请确保GPS,WiFi和蜂窝网络启用。可以如截图显示设置:Google设置——位置——模式

    如下截图演示了利用GetBestProvider获取位置的位置应用:

    请记住,GetBestProvider不会动态更新提供程序。相反,它在Activity的生命周期中只确定一次最佳提供程序。如果在已经获取过提供程序后,提供程序状态发生了变化,应用则需要为ILocationListener中的方法(OnProviderEnabled, OnProviderDisabled, 和 OnStatusChanged)添加额外的代码来处理提供程序的切换。

    为了使常见场景变得简单,以及使用较少的代码,Google为我们引入了FusedLocationProvider来处理提供程序的改变。FusedLocationProvider是Google位置服务API的一部分,Google位置服务是附加在Google Play服务上的。我们将在下面介绍它。

    通过Google位置服务和FusedLocationProvide获取位置

    由于国内大部分厂商提供的Android机都没有Google服务,故此处暂不做翻译。
    原文见:Get Location with Google Location Services and the Fused Location Provider
    原文示例代码


    译:奇葩史

  • 相关阅读:
    递归和消去递归
    Time complexity analysis of algorithms
    algorithms中计算时间的渐近表示
    OAuth认证协议原理分析及同步消息到Twitter和Facebook使用方法
    javascript实现URL编码与解码
    before伪类的超有用应用技巧——水平菜单竖线分隔符
    在线工具(转)
    程序员小抄大全
    Web设计的速查卡(转)
    一个简单的AJAX示例(转)
  • 原文地址:https://www.cnblogs.com/huaxia283611/p/Location-Services.html
Copyright © 2011-2022 走看看