返回索引目录
原文链接: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位置服务获取用户位置,我们需要以下操作:
- 添加对LocationManager类的引用
- 使用LocationManager向特定的服务程序请求位置更新
- 实现ILocationListener接口,并在其中处理位置改变事件。
- 当应用进入后台时,停止位置更新。
位置服务
位置服务是系统中服务管理的一种特殊类型。系统服务和硬件设备交互,并一直保持运行。要在 我们的应用中使用位置更新,我们需要利用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。
原文示例代码
译:奇葩史
[译]:Xamarin.Android平台功能——位置服务的更多相关文章
-
Xamarin.Android其他类型的服务
一.前言 前面我们已经学了关于服务的很多知识,但是对于真实的开发那些远远不够,通过这节我们将学习其他类型的服务,比如前台服务.IntentService和消息服务.下面我们开始进入正题. 二.前台服务 ...
-
android中的位置服务(LBS)
自己的位置:LocationManager 基本用法:创建实例:LocationManager locationManager = (LocationManager)getSystemService ...
-
XAMARIN ANDROID 二维码扫描示例
现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile 做一个简单的 Android 条码扫描示 ...
-
Xamarin.Android开发实践(八)
Xamarin.Android其他类型的服务 一.前言 前面我们已经学了关于服务的很多知识,但是对于真实的开发那些远远不够,通过这节我们将学习其他类型的服务,比如前台服务.IntentService和 ...
-
6.关于Xamarin Android对APK包大小的处理
降低学习成本是每个.NET传教士义务与责任. 建立生态,保护生态,见者有份. 对于apk 包的大小大家都是很敏感的,虽然现在安卓手机的性能和存储越来越厉害了.本着能少一点是一点的态度,我们还是要深入理 ...
-
[译]:Xamarin.Android开发入门——Hello,Android Multiscreen深入理解
原文链接:Hello, Android Multiscreen_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android Multiscreen深入理解. 本 ...
-
[译]:Xamarin.Android开发入门——Hello,Android深入理解
返回索引目录 原文链接:Hello, Android_DeepDive. 译文链接:Xamarin.Android开发入门--Hello,Android深入理解 本部分介绍利用Xamarin开发And ...
-
xamarin.android 消息推送功能--极光推送
最近在使用xamarin.android的消息推送功能,官方使用的例子是FCM方式,按照官方文档,使用FQ软件是可以成功的,但是在国内由于众所周知的原因,在国内服务并不能使用,于是查找国内各自推送平台 ...
-
[译]:Xamarin.Android开发入门——Hello,Android Multiscreen快速上手
原文链接:Hello, Android Multiscreen Quickstart. 译文链接:Hello,Android Multiscreen快速上手 本部分介绍利用Xamarin.Androi ...
随机推荐
-
JAVA 问题集中之处以及解决的办法
也许当你看的时候,你可能认为这些都是简单的问题,有什么好记的.其实不是,我认为,我们往往是因为粗心而造成的错误,当你在开发中碰到这些问题时,你能一下看出来是什么错误,达到提高效率.而且往往你把小的问题 ...
-
GitHub 使用教程图文详解(转)
大纲: 一.前言 二.GitHub简介 三.注册GitHub账号 四.配置GitHub 五.使用GitHub 六.参与GitHub中其它开源项目 七.总结 注,GitHub官网:https://git ...
-
Android 如何直播RTMP流
在android上,视频/音频流直播是极少有人关注的一部分.每当我们讨论流媒体,RTMP(Real Time Messaging Protocol)是不可或缺的.RTMP是一个基本的视频/音频直播流协 ...
-
让你的Xcode8 支持 iOS7
Xcode8 发布,更新后,发现支持从iOS8开始,可是公司要求从iOS7开始,,,这和苹果相悖. 不过没关系. 跳转 www.cnblogs.com/starainDou/p/5325643.htm ...
-
SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE locks在RR模式下可以看到最新的记录
14.5.2.4 Locking Reads 锁定读: 如果你查询数据然后插入或者修改相关数据在相同的事务里, 常规的SELECT 语句不能给予足够的保护. 其他事务可以修改或者删除你刚查询相同的记录 ...
-
EMV标准
EMV标准是由国际三大银行卡组织--Europay(欧陆卡,已被万事达收购).MasterCard(万事达卡)和Visa(维萨)共同发起制定的银行卡从磁条卡向智能IC卡转移的技术标准,是基于IC卡的金 ...
-
学习笔记之C++入门到精通(名师教学·手把手教会)【职坐标】_腾讯课堂
C++入门到精通(名师教学·手把手教会)[职坐标]_腾讯课堂 https://ke.qq.com/course/101465#term_id=100105503 https://github.com/ ...
-
uboot 的命令体系
1.代码位置 (1)uboot命令体系的实现代码在uboot/common/cmd_xxx.c中.有若干个.c文件和命令体系有关.(还有command.c main.c也是和命令有关的) 2.传参方 ...
-
分享一个展示文章列表的CSS样式
最近在帮朋友处理一个网站前端显示文章列表的时候,其中有个变通的思路,现整理出来留给有需要的朋友参考及自己备忘. 显示效果为:标题左对齐,日期右对齐. 标题和日期中间用常规的原点(“.”) 代替,显示效 ...
-
JS apply 和 call 的实现
很早之前的一篇博客写了bind的实现,是基于apply的,感兴趣的朋友看完这篇文章可以接着看看bind的实现. apply 和 call 主要就是传参的区别.这里就不多说了,直接看代码. //call ...