Knowing where the user isallows your application to be smarter and deliver better information to theuser. When developing a location-aware application for Android, you can utilizeGPS and Android's Network Location Provider to acquire the user location.Although GPS is most accurate, it only works outdoors, it quickly consumesbattery power, and doesn't return the location as quickly as users want.Android's Network Location Provider determines user location using cell towerand Wi-Fi signals, providing location information in a way that works indoorsand outdoors, responds faster, and uses less battery power. To obtain the userlocation in your application, you can use both GPS and the Network LocationProvider, or just one.
知道用户在那可以让你的应用更加智能化并且可以为用户提供更佳的信息。当开发一个可感知位置的Android应用时,你可以使用Android的GPS定位器和Network定位器去获取用户的位置信息。虽然GPS定位是最准确的,但只能在户外使用,会大量的消耗电池,并且不能迅速的返回位置信息。Android的Network定位通过基站和Wi-Fi信号来确定用户位置,它提供了一种快速返回,消耗少量电能,室内和室外都可使用的定位方式。为了获得用户位置,你可以使用GPS定位器和Network定位器,或者只用其中之一。
确定用户位置的难点
Obtaining user locationfrom a mobile device can be complicated. There are several reasons why alocation reading (regardless of the source) can contain errors and beinaccurate. Some sources of error in the user location include:
通过手机设备获得用户的位置可能会是很复杂的。这里有几个原因关于为什么定位会存在错误或是不正确的。定位错误的原因包括:
·Multitude oflocation sources
多个位置来源
GPS,Cell-ID, and Wi-Fi can each provide a clue to users location. Determining whichto use and trust is a matter of trade-offs in accuracy, speed, andbattery-efficiency.
GPS,Cell-ID, Wi-Fi都能提供用户位置的线索。要平衡精度,速度和电池效率等因素来决定使用和相信哪一个来源。
·User movement
用户的移动
Becausethe user location changes, you must account for movement by re-estimating userlocation every so often.
因为用户的位置变更,你必须经常的重新确定用户位置。
·Varyingaccuracy
多样的精度
Locationestimates coming from each location source are not consistent in theiraccuracy. A location obtained 10 seconds ago from one source might be moreaccurate than the newest location from another or same source.
These problems can make itdifficult to obtain a reliable user location reading. This document providesinformation to help you meet these challenges to obtain a reliable locationreading. It also provides ideas that you can use in your application to providethe user with an accurate and responsive geo-location experience.
位置的评估是从多个精度不一的定位设备获得的。一个10秒钟之前获得的位置可能比从另一个或者当前定位器获得最新位置更精确。
这些问题使得获得可靠的用户位置信息变的困难。这个文档提供信息可以让你面对这些挑战而获得可靠的用户位置。它同样还提供了一些方法可以让你的程序为用户提供快速响应地理位置的体验。
位置更新
Before addressing some ofthe location errors described above, here is an introduction to how you canobtain user location on Android.
在讨论上述错误之前,这里有个一怎样在Android总获得用户位置的说明。
Getting user location inAndroid works by means of callback. You indicate that you'd like to receivelocation updates from theLocationManager
("Location Manager") by callingrequestLocationUpdates()
, passing it aLocationListener
. YourLocationListener
must implement several callback methods that the LocationManager calls when the user location changes or when the status of the servicechanges.
在Android上获得用户位置使用的是回调的方式。你使用LocationManager
中的requestLocationUpdates()
方法表明你想接收位置更新信息,同时传入参数LocationListener
。你传入的LocationListener
必须实现了回调方法,让Manager在位置或服务改变的时候调用。
For example, the followingcode shows how to define aLocationListener
and request location updates:
以下代码演示如何定义一个LocationListener
和请求位置更新:
// 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);
The first parameter inrequestLocationUpdates()
is the type of location provider to use (in this case, theNetwork Location Provider for cell tower and Wi-Fi based location). You cancontrol the frequency at which your listener receives updates with the secondand third parameter—the second is the minimum time interval betweennotifications and the third is the minimum change in distance betweennotifications—setting both to zero requests location notifications asfrequently as possible. The last parameter is yourLocationListener
, which receives callbacks for location updates.
requestLocationUpdates()
方法的第一个参数location provider类型的(在这里是基于基站和Wi-F的Network定位)。你可以通过第二个和第三个参数设置监听器接收更新的频率—第二个参数是接收通知的最小时间间隔,第三个参数是通知之间最小的距离间隔,把他们都设置为0表示尽可能快的接收位置更新通知。最后一个参数就是你的LocationListener
,用来接收位置更新的反馈。
To request locationupdates from the GPS provider, substituteGPS_PROVIDER
forNETWORK_PROVIDER
. You can also request location updates from both the GPS andthe Network Location Provider by callingrequestLocationUpdates()
twice—once forNETWORK_PROVIDER
and once forGPS_PROVIDER
.
为了从GPS得到位置更新,用GPS_PROVIDER代替NETWORK_PROVIDER。你可以调用两次requestLocationUpdates()
方法,一次请求GPS一次请求NETWORK。这样就可以同时从两个定位器获得位置信息更新。
In order to receivelocation updates fromNETWORK_PROVIDER
orGPS_PROVIDER
, youmust request user permission by declaring either theACCESS_COARSE_LOCATION
orACCESS_FINE_LOCATION
permission, respectively, in your Android manifest file. Forexample:
为了能从NETWORK_PROVIDER
或者GPS_PROVIDER
中获得位置更新信息,你必须在manifest文件中声明ACCESS_COARSE_LOCATION
或者ACCESS_FINE_LOCATION
权限。如下:
<manifest ... > <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ... </manifest>
Without these permissions,your application will fail at runtime when requesting location updates.
没有这些权限,你的应用会在请求位置信息的时候出错。
Note:If you areusing bothNETWORK_PROVIDER
andGPS_PROVIDER
, thenyou need to request only theACCESS_FINE_LOCATION
permission, because it includes permission for bothproviders. (Permission forACCESS_COARSE_LOCATION
includes permission only forNETWORK_PROVIDER
.)
如果你NETWORK_PROVIDER
和GPS_PROVIDER
定位器都使用了,那你只需要ACCESS_FINE_LOCATION
权限,因为它都包括了。(ACCESS_COARSE_LOCATION
只包含了NETWORK_PROVIDER
所要的权限)
Location-basedapplications are now commonplace, but due to the less than optimal accuracy,user movement, the multitude of methods to obtain the location, and the desireto conserve battery, getting user location is complicated. To overcome theobstacles of obtaining a good user location while preserving battery power, youmust define a consistent model that specifies how your application obtains theuser location. This model includes when you start and stop listening forupdates and when to use cached location data.
基于位置的应用现在很常见了。但是由于精度,用户移动,获得定位的多种方式和对电量的保存,获得用户位置是复杂的。为了克服这些困难并且在节省电量的情况下获得好的用户定位,你必须定义一个获取用户定位的模式。这个模式包括了你该在什么时候开始和停止监听位置更新信息和什么时候使用缓存的位置信息。
获得定位的流程
Here's the typical flow ofprocedures for obtaining the user location:
1.Startapplication.
2.Sometimelater, start listening for updates from desired location providers.
3.Maintain a"current best estimate" of location by filtering out new, but lessaccurate fixes.
4.Stop listeningfor location updates.
5.Take advantageof the last best location estimate.
1.启动程序
2.然后开始监听位置更新信息
3.通过过滤掉较新但是精度低的位置信息,来维持一个最佳定位
4.停止监听
5.使用最新得到的最佳定位
Figure 1 demonstrates thismodel in a timeline that visualizes the period in which an application islistening for location updates and the events that occur during that time.
图1用时间轴形象的显示一个程序监听位置信息和这段时间内发生的事件
Figure 1.A timelinerepresenting the window in which an application listens for location updates.
This model of a window—duringwhich location updates are received—frames many of the decisions you need tomake when adding location-based services to your application.
这个窗口模型(在接收位置更新信息期间)表达了很多你在添加基于位置的服务到你应用时所需要作出的决定。
决定合适开始监听更新
You might want to startlistening for location updates as soon as your application starts, or onlyafter users activate a certain feature. Be aware that long windows of listeningfor location fixes can consume a lot of battery power, but short periods mightnot allow for sufficient accuracy.
你可能希望应用一开启就监听位置更新信息或者进行某些操作时开始。要意识到长时间的监听位置更新会消耗很多电量,但是短期的监听可能精度高。
As demonstrated above, youcan begin listening for updates by callingrequestLocationUpdates()
:
综上所述,你可以调用requestLocationUpdates()
方法开始监听
LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER; // Or, use GPS location data: // LocationProvider locationProvider = LocationManager.GPS_PROVIDER; locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
使用最新已知位置进行一次校准
The time it takes for yourlocation listener to receive the first location fix is often too long for userswait. Until a more accurate location is provided to your location listener, youshould utilize a cached location by callinggetLastKnownLocation(String)
:
第一次从监听器接收到位置校准信息可能会让用户等太长时间。知道从监听器得到一个比较准确的信息,你应该调用getLastKnownLocation(String)
来使用一个缓存的定位信息。
LocationProvider locationProvider = LocationManager.NETWORK_PROVIDER; // Or use LocationManager.GPS_PROVIDER Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
决定合适停止监听更新
The logic of deciding whennew fixes are no longer necessary might range from very simple to very complexdepending on your application. A short gap between when the location isacquired and when the location is used, improves the accuracy of the estimate.Always beware that listening for a long time consumes a lot of battery power,so as soon as you have the information you need, you should stop listening forupdates by callingremoveUpdates(PendingIntent)
:
决定不再需要新的校准信息的可能是很简单或者很复杂。在获得定位信息和定位信息被使用的小间隔中提高估计精度。永远要意识到长时间的监听是很耗电的,当你一拿到你所需要的信息,你就应该调用removeUpdates(PendingIntent)
停止监听
// Remove the listener you previously added locationManager.removeUpdates(locationListener);
维护一个现有最佳估计
You might expect that themost recent location fix is the most accurate. However, because the accuracy ofa location fix varies, the most recent fix is not always the best. You shouldinclude logic for choosing location fixes based on several criteria. Thecriteria also varies depending on the use-cases of the application and fieldtesting.
你可能希望最新获得的就是最准确的。可是,获得的校准的精度是不同,所以最新获得的并不一定是最准确的。你应该用一些标准选择最佳的校准。这些标准也是根据应用的用途而变化的。
Here are a few steps youcan take to validate the accuracy of a location fix:
这里是检验最佳精度的步骤
·Check if thelocation retrieved is significantly newer than the previous estimate.
·Check if theaccuracy claimed by the location is better or worse than the previous estimate.
·Check whichprovider the new location is from and determine if you trust it more.
检查位置信息是不是明显比上一次新
检查位置信息的精度比上次高还是低
检查位置的来源,你是否相信他
An elaborate example ofthis logic can look something like this:
一个详尽的范例逻辑
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); }
As you test yourapplication, you might find that your model for providing good location andgood performance needs some adjustment. Here are some things you might changeto find a good balance between the two.
调整模型去节省电量和交换数据
A当你测试你应用,我也许会发现你听过定位的模型需要惊喜调整。这里有几个你可能会改变的地方。
减小窗口尺寸
A smaller window in whichyou listen for location updates means less interaction with GPS and networklocation services, thus, preserving battery life. But it also allows for fewerlocations from which to choose a best estimate.
监听的窗口小以为着和GPS或者network定位服务的交互少,因此,省电。但是这也减少了可供选择的最佳位置。
Reducing the rate at whichnew updates appear during the window can also improve battery efficiency, butat the cost of accuracy. The value of the trade-off depends on how yourapplication is used. You can reduce the rate of updates by increasing theparameters inrequestLocationUpdates()
that specify the interval time and minimum distance change.
降低提供更新的频率
降低更新频率可以节省电量,但会损失精度。之间的取舍要看你应用的用途。你可以调用requestLocationUpdates()
方法来指定间隔时间和最小更新距离。
限制一组providers
Depending on theenvironment where your application is used or the desired level of accuracy,you might choose to use only the Network Location Provider or only GPS, insteadof both. Interacting with only one of the services reduces battery usage at apotential cost of accuracy.
根据你应用使用的环境或者期望的精度,你可能只用Network或者GPS其中一个定位,而不是2个一起。只和其中一个进行交互可能会损失精度。
There are many reasons youmight want to obtain the user location in your application. Below are a couplescenarios in which you can use the user location to enrich your application.Each scenario also describes good practices for when you should start and stoplistening for the location, in order to get a good reading and help preservebattery life.
You might be creating anapplication where user-created content is tagged with a location. Think of userssharing their local experiences, posting a review for a restaurant, orrecording some content that can be augmented with their current location. Amodel of how this interaction might happen, with respect to the locationservices, is visualized in figure 2.
Figure 2.A timelinerepresenting the window in which the user location is obtained and listeningstops when the user consumes the current location.
This lines up with theprevious model of how user location is obtained in code (figure 1). For bestlocation accuracy, you might choose to start listening for location updateswhen users begin creating the content or even when the application starts, thenstop listening for updates when content is ready to be posted or recorded. Youmight need to consider how long a typical task of creating the content takesand judge if this duration allows for efficient collection of a location estimate.
You might be creating anapplication that attempts to provide users with a set of options about where togo. For example, you're looking to provide a list of nearby restaurants,stores, and entertainment and the order of recommendations changes depending onthe user location.
To accommodate such aflow, you might choose to:
·Rearrangerecommendations when a new best estimate is obtained
·Stop listeningfor updates if the order of recommendations has stabilized
This kind of model isvisualized in figure 3.
Figure 3.A timelinerepresenting the window in which a dynamic set of data is updated each time theuser location updates.
As you develop yourapplication, you'll certainly need to test how well your model for obtaininguser location works. This is most easily done using a real Android-powereddevice. If, however, you don't have a device, you can still test yourlocation-based features by mocking location data in the Android emulator. Thereare three different ways to send your application mock location data: usingEclipse, DDMS, or the "geo" command in the emulator console.
Note:Providing mocklocation data is injected as GPS location data, so you must request locationupdates fromGPS_PROVIDER
in order formock location data to work.
SelectWindow>ShowView>Other>EmulatorControl.
In the Emulator Controlpanel, enter GPS coordinates under Location Controls as individual lat/longcoordinates, with a GPX file for route playback, or a KML file for multipleplace marks. (Be sure that you have a device selected in the Devicespanel—available fromWindow>ShowView>Other>Devices.)
With the DDMS tool, youcan simulate location data a few different ways:
·Manually sendindividual longitude/latitude coordinates to the device.
·Use a GPX filedescribing a route for playback to the device.
·Use a KML filedescribing individual place marks for sequenced playback to the device.
For more information onusing DDMS to spoof location data, seeUsing DDMS.
To send mock location datafrom the command line:
1.Launch yourapplication in the Android emulator and open a terminal/console in your SDK's/tools
directory.
2.Connect to theemulator console:
telnet localhost <console-port>
3.Send thelocation data:
ogeo fix
to send afixed geo-location.
Thiscommand accepts a longitude and latitude in decimal degrees, and an optionalaltitude in meters. For example:
geo fix -121.45356 46.51119 4392
ogeo nmea
to send anNMEA 0183 sentence.
Thiscommand accepts a single NMEA sentence of type '$GPGGA' (fix data) or '$GPRMC'(transit data). For example:
geo nmea $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
For information about howto connect to the emulator console, seeUsing the Emulator Console.
ps:翻译到最后失去兴趣了,就这么发表吧~~~~