知道用户的位置信息可以使你的程序更加的智能并且能够提供更好的信息给你的用户,当开发一个位置感知的程序的时候,你可以使用gps或者是android的网络位置提供者来获取用户的位置。虽然使用GPS最精确,但是他仅能工作在户外,并且他更耗电量,还不能及时的返回用户的位置信息。相比较而言,android的网络位置提供者通过基站或者是WI-FI信号来判断用户的位置,它既能工作在户外,也能工作在室内,反应迅速,耗电较少。你可以同时使用这两种方式来获得位置信息,也可以使用这两种方式中的一种。
通过用户的移动设备获取位置信息是很复杂的,有这么几个原因导致获取位置时发生错误。
原因如下:
-
-
- 有多种方式获取位置,可以通过GPS,Cell-ID, Wi-Fi等等,这三种方式都能让你获取位置信息,判断使用哪种方式获得的信息会牵扯到精度,响应速度和电量耗费等等问题。
- 用户不断的移动,那么你必须不断的去估算用户的位置信息
- 不断变化的精度 从一个位置源获取的位置信息并不是一成不变的,10秒钟前你在A位置源获取的位置信息可能比你从A 处或者是B处获取的最新的位置信息要精确。
1. 请求位置更新
在定位上述的一些问题之前,让我们先来看看如何在android上获取位置信息。
在Android上通过回调的方式来获取用户位置信息,通过LocationManager的requestLocationUpdates(),方法,你就可以注册当前的Activity给LocationManager,那么这个LocationManager就能够周期性的通知这个已经注册了的activity最新的位置信息,这个activity必须提供监听器以让LocationManager对调,提供的监听器必须要实现LocationListener的如下几个方法,当用户的位置或者是网络位置服务的状态发生改变时,这几个方法就会被LocationManager回调。
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
引申:让我们来看看上述代码用到的相关的api
LocationManager: 这个类让你能够使用系统的位置服务,这些服务能够让android程序周期性的获得设备的物理位置的更新,或者是 当用户接近一个特别的物理位置的时候,应用程序能够发送一个特殊的意图提醒用户。你不能实例化这个类获得该类的实例对象,而是通过Context.getSystemService(Context.LOCATION_SERVICE)来获取句柄
public void requestLocationUpdates (Stringprovider, long minTime, float
minDistance,LocationListenerlistener)
注册当前的activity能够被指定的provider周期性的通知。如果当前的位置或者是指定provider的状态发生变化的时候,当前activity提供的LocationListener会被周期性的调用。获取最新的位置信息需要消耗一些时间,应用程序可以通过getLastKnownLocation(String)
方法得到一个最接近的位置(这个地方还有待斟酌)。
如果当前provider服务被用户关闭的话,注册更新就会停止,provider的状态就会变为disable,onProviderDisabled(String)方法就会被调用。一旦当前provider又被打开,那么onProviderEnabled就会被调用,注册更新又会重新开始。
通过第二个和第三个参数能够控制位置更新的频率。第一个参数minTime代表两次位置更新之间的时间间隔,如果minTime大于0,那么LocationManager就会在一次更新完后,休息minTime时间,然后继续更新,这样能够节省电量。第三个参数minDistance是一个位置更新的条件,因为用户的位置可能是不断变化的,当前后两次位置的距离大于minDistance的时候,才会更新。如果想尽快得到获取更新,那么把这两个参数都设为0吧。
当保持GPS或者是无线网络服务一直运行的时候,后台的服务应当设置充分的时间间隔以至于设备不会消耗太多的电量,小于60000毫秒的时间间隔是不被推荐的。
调用位置服务的线程必须是含有looper的线程。
Locationandroid.location.LocationManager.getLastKnownLocation(Stringprovider)
从指定provider上获取最后一个位置修正的信息,即时不开启这个provider也能使用这个方法,但是这个时候这个provider的状态为disable,该函数的返回值为null,注意这个返回值location有可能国企,例如关闭移动设备或者是移动到其他的位置。
问题:
1. 系统是如何缓存位置修正信息的?
getLastKnownLocation方法获取的是最后一个缓存的位置信息,当调用requestLocationUpdates方法的时候,位置服务就会开始不断的缓存更新的位置修正信息,当调用了removeUpdates方法停止更新的时候,缓存就会停止,这个时候调用getLastKnownLocation方法,获取的就是最后一个缓存的位置修正信息。由于缓存的位置信息有可能过期,所以你需要判断返回值是否为null,并作特殊处理。
2. 在手机上如何开启位置服务呢?
以我的G3为例,打开“设置”-----》“位置“,就会看到如下界面
第一个对应NETWORK_PROVIDER
第二个对应GPS_PROVIDER
如果这里不打开服务的话,你的程序是无法获取位置信息的。
2. 位置服务的权限设置
为了使用NETWORK_PROVIDER or GPS_PROVIDER来获取位置信息,你必须要在程序中配置用户的权限,获取用户的位置信息需要权限ACCESS_COARSE_LOCATION 或者ACCESS_FINE_LOCATION
<manifest ... >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
</manifest>
注意:如果你使用NETWORK_PROVIDER 和GPS_PROVIDER 两种方式的话,你只需要声明ACCESS_FINE_LOCATION这个权限就可以了,它包括了这两种provider所需要的权限。ACCESS_COARSE_LOCATION权限仅仅声明了NETWORK_PROVIDER所需要的权限
3. 定义一个获取用户配置信息的最好的模型
一个基本的获取获取位置信息的程序是简单的,但是如果要考虑到位置信息的精度,用户的移动,获取位置的方法,对于手机电量的需求,获取位置是很复杂的。
你必须建立一个模型来指导你的程序如何去获得用户位置,这个模型演示了什么时候监听和移除监听位置更新,什么时候缓存位置信息数据
获取用户位置信息的步骤
- 开启程序
- 开始监听位置的更新
- 确定一个最好的当前的位置信息
- 停止监听
- 使用最好的位置信息
4. 具体实现步骤
4.1 确定什么时间开始监听更新
你可能在程序启动启动起来之后就立即开始监听位置更新,或者是在用户某个动作之后监听。你需要知道的是长时间的监听位置信息的修正很快消耗掉很多电量,但是短时间内又无法获得充分精确地信息
LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER;
// Or, use GPS location data:
// LocationProvider locationProvider = LocationManager.GPS_PROVIDER;
locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
4.2 使用上一个已知的位置来得到一个快速的位置修正
LocationListener获取第一个位置修正的时间会很长,为了避免用户等待,在你的LocationListener获取到一个更加精确的位置之前,你应当使用getLastKnownLocation(String)获取一个缓存的位置。
LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER;
// Or use LocationManager.GPS_PROVIDER
Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
4.3 确定什么时候停止监听位置更新
确定什么时候那些新的位置修正不在需要的逻辑是简单还是复杂取决于你的应用程序。位置信息被得到的时间和位置信息被使用的时间之间的间隔越短,位置预估的精度就越高。时刻要注意,长时间的监听位置更新会消耗大量电量。一旦得到你所需要的信息之后,你应当立即调用removeUpdates(PendingIntent)方法停止监听。
// Remove the listener you previously added
locationManager.removeUpdates(locationListener);
注意:这个方法必须调用,如果不调用这个方法,即时你退出了程序,仍然会被更新。
4.4 确定一个最精确的当前位置信息
你可能认为最新的位置修正时最精确的,然而因为位置修正的精度各种各样,最新的位置修正也不一定是最好的。你应当引入一个逻辑来根据一些条件来选择最好的位置修正。这些条件取决于你的程序
下面是一些你可以用来验证位置修正的步骤
验证是否获得的位置是否明显的比上一个要新
验证这个位置的精度比上一个位置的精度高还是低
验证这个位置那个provider提供的并且判断这个provider是否可信
下面就是一个详尽的判断的例子:
private static final int TWO_MINUTES = 1000 * 60 * 2;/** Determines whether one Location reading is better than the current Location fix
* @param location The new Location that you want to evaluate
* @param currentBestLocation The current Location fix, to which you want to compare the new one
*/
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
转自:http://www.cnblogs.com/transmuse/archive/2010/12/31/1923358.html
分享到:
相关推荐
在互联网行业中,获取和运营核心用户是至关重要的环节,它直接影响到产品的长期发展与成功。这份资料"核心用户获取和运营策略(内含小红书、在行案例)"深入探讨了这一主题,通过具体的小红书和在行平台的案例,为我们...
3. **PDFSlide**则强调简洁明了的设计风格,便于观众快速获取关键信息。 #### 四、跨平台的LaTeX实践 ##### Linux环境下的LaTeX使用 - 在Linux系统中,可以很方便地通过包管理器安装LaTeX相关的软件。 - 例如,在...
### 安全认证框架-Apache Shiro研究心得 #### Apache Shiro简介 Apache Shiro 是一个强大且易用的 Java 安全框架,提供了认证、授权、加密和会话管理功能,可以非常容易地开发出足够安全的应用——无论它们是部署...
另一本"搜索引擎与信息获取技术.pdf"很可能详细阐述了搜索引擎的工作原理、信息检索理论以及最新的研究进展。这将帮助读者理解搜索引擎背后的复杂机制,以及如何运用这些知识改进信息获取的效率。 “搜索笔记.doc”...
智能电网还具有信息技术、传感器技术、自动操纵技术与电网根底设备的有机交融,可以获取电网的全景信息,及时觉察、预见可能发生的缺点。 三、智能电网的应用前景 智能电网可以实现实时和非实时信息的高度集成、...
在社交平台上,用户生成的内容往往是多维度的,除了评价商品质量外,还可能涉及使用心得、使用场景、相关生活经验分享等,这些内容丰富了商品信息的维度,使得推广更加自然和具有说服力。因此,探究移动电商市场结构...
3. **应用商店**:如App Store和Google Play,它们不仅是下载游戏的地方,也是获取游戏介绍、更新信息和用户评价的直接渠道。 4. **游戏论坛**:如NGA玩家社区、百度贴吧等,玩家可以在这里交流游戏心得,分享攻略...
地理信息系统(GIS)是一种集成计算机硬件、软件、地理数据以及系统管理人员的综合系统,它能够高效地进行地理信息的获取、存储、更新、操作、分析及显示。GIS的核心在于其能够处理复杂的图形数据,包括点、线、多边形...
信息检索是现代社会中至关重要的技能,它涉及到如何高效地寻找、筛选和利用各种信息资源,无论是对于学术研究还是日常生活都有着深远的影响。以下是对信息检索相关知识点的详细说明: 首先,信息检索的基础是理解和...
信息化系统的实施有助于实现部门间的信息互通,例如在许可证管理中,通过建立客户信息数据库,使得销售、配送等部门能够实时获取并利用这些信息。这样不仅有助于降低管理成本,还能极大提升工作效率,实现精细化管理...
总的来说,【食药云搜】专业信息搜索APP是医药行业从业人员和学者的重要工具,它通过集成丰富的医药信息资源,强大的数据分析能力,以及贴心的用户服务,助力用户在繁忙的工作和研究中高效获取和理解专业信息。...
1. 信息获取:通过互动,用户可以获得更全面的商品信息,有助于他们做出购买决策。主播的实时解答能解决用户疑虑,增加购买信心。 2. 情感共鸣:互动增强了用户与主播和品牌的感情连接,这种情感因素可能超过理性的...
10. **持续学习与社区参与**:ArcGIS技术更新快速,开发者需要保持学习态度,关注Esri官方文档、博客、论坛,积极参与社区交流,以便获取最新信息和技术支持。 通过深入研究这份"ArcGIS接口详细说明之个人开发心得...
此外,物联网不仅仅是数据传输,它还具备智能处理能力,通过云计算和模式识别等技术,对收集到的海量信息进行分析,挖掘出有价值的数据,以满足不同用户的需求,推动新的应用领域的发展。 物联网可以根据服务范围和...
安装完成后,需将安装文件中的license文件复制到系统盘根目录下指定位置,以便软件正确识别许可信息。同时,需要注意解决Gambit在运行过程中可能出现的问题,例如删除*.lok文件以解决程序异常退出的情况。 #### 三...
通过网络,我们可以查阅到大量的资料,无论是学术研究还是日常生活中需要的信息,都能在短时间内找到。同时,网络通信工具如电子邮件、社交媒体等,极大地拉近了人与人之间的距离,使得跨地域的交流变得简单快捷。 ...
将新闻标题与详细内容连接起来,需要进一步筛选数据库记录,例如仅根据ID获取特定新闻的详细信息。这样,当用户点击新闻标题时,可以跳转到包含详细内容的单独页面。 最后,切记在每次编辑后保存你的网页,因为很多...