如果应用程序可以连续跟踪定位,它可以提供更多的相关信息给用户。 例如,如果你的应用程序可以帮助用户找到自己的方式,如步行或开车,或者如果您的应用程序获知商店的位置,它需要定期来获得设备的位置。 以及地理位置(经纬度),您可能希望给用户提供更多的信息,如坐标轴(行程水平方向),高度或速度的设备。 这个信息,更多的,是在现有的Location对象,你的应用程序可以从检索混合的位置信息 。
虽然你可以从getLastLocation()得到一个设备的位置,如关于课程说明获取最后已知的位置 ,但更直接的方法是从混合位置提供者要求定期更新。 对此,API更新您提供当前最佳的位置周期性应用的基础上,当前可用的位置,供应商,如WiFi和GPS(全球定位系统)。 位置的精确度是由您在位置请求设置供应商,您所要求的位置的权限和选项确定。
本课向您展示如何请求有关使用设备的位置,定期更新requestLocationUpdates()的融合位置提供方法。
获得最后的已知位置
该设备的最后已知的位置会提供一个启动一个方便的基地,确保应用程序有启动周期性位置更新之前已知位置。 关于课程获得最后一个已知的位置展示了如何通过调用获得最后一个已知位置getLastLocation() 在下面的章节中片段假定您的应用程序已检索到的最后已知位置并存储它作为一个Location在全局变量对象mCurrentLocation 。
使用位置服务必须请求位置信息访问权限的应用程序。 在这一课中,你需要精确的位置信息检测,使您的应用程序可以从现有的位置提供得到尽可能精确的位置成为可能。 要求与本许可uses-permission元素应用清单,如下面的例子:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
请求位置更新
请求位置更新之前,您的应用程序必须连接到定位服务,并作出定位请求。 关于课程更改位置设置展示了如何做到这一点。 一旦一个位置的要求是在地方,你可以通过调用启动定期更新requestLocationUpdates() 在执行此操作onConnected()由谷歌API客户端,当客户准备好这就是所谓提供的回调。
根据请求的形式,熔化的位置提供在任调用LocationListener.onLocationChanged()回调方法,并传递它一个Location对象,或发出PendingIntent包含在其扩展数据的位置。 更新的准确性和频率由您在位置请求对象设定您所要求的位置,权限和选项的影响。
本课向您展示如何开始使用更新LocationListener回调方法。 呼叫requestLocationUpdates()向它传递的您的实例GoogleApiClient的LocationRequest对象和LocationListener 。 定义一个startLocationUpdates()方法,从被叫onConnected()回调,如以下代码示例中:
@Override
public void onConnected(Bundle connectionHint) {
...
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
请注意,上面的代码片段是指一个布尔标志, mRequestingLocationUpdates ,用于跟踪用户是否打开或关闭位置更新。 欲了解更多有关保留这个标志的整个活动的情况下的价值,看到保存活动的国家 。
定义位置更新的回调
融合的位置提供调用LocationListener.onLocationChanged()回调方法。 传入的参数是一个Location包含位置的经度和纬度对象。 下面的代码片段展示了如何实现LocationListener接口和定义方法,然后得到位置更新的时间戳,并显示您的应用程序的用户界面上的纬度,经度和时间戳:
public class MainActivity extends ActionBarActivity implements
ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
...
@Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
private void updateUI() {
mLatitudeTextView.setText(String.valueOf(mCurrentLocation.getLatitude()));
mLongitudeTextView.setText(String.valueOf(mCurrentLocation.getLongitude()));
mLastUpdateTimeTextView.setText(mLastUpdateTime);
}
}
停止位置更新
考虑是否要停止位置更新时的活动不再处于焦点,当用户切换到另一个应用程序,如,或在同一应用不同的活动。 这可以方便地降低功耗,提供的应用程序并不需要收集的信息,即使它在后台的运行。 本节将展示如何在活动的停止更新onPause()方法。
要停止位置更新,呼叫removeLocationUpdates()向它传递的您的实例GoogleApiClient对象和一个LocationListener ,如下面的代码示例:
@Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
使用一个布尔值, mRequestingLocationUpdates ,追踪位置更新当前是否开启。 在活动的onResume()方法,检查位置更新当前是否处于活动状态,如果没有激活它们:
@Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) {
startLocationUpdates();
}
}
保存活动的状态
该设备的结构的变化,如在屏幕取向或语言的改变,可引起当前活动被破坏。 因此,您的应用程序必须存储它需要重新创建活动的任何信息。 这样做的一个方法是通过存储在一个实例的状态Bundle对象。
下面的代码示例演示如何使用该活动的onSaveInstanceState()回调来保存实例状态:
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,
mRequestingLocationUpdates);
savedInstanceState.putParcelable(LOCATION_KEY, mCurrentLocation);
savedInstanceState.putString(LAST_UPDATED_TIME_STRING_KEY, mLastUpdateTime);
super.onSaveInstanceState(savedInstanceState);
}
定义一个updateValuesFromBundle()方法从活动的一个实例恢复保存的值如果他们提供。 从活动的调用该方法onCreate()方法,如下面的代码示例:
@Override
public void onCreate(Bundle savedInstanceState) {
...
updateValuesFromBundle(savedInstanceState);
}
private void updateValuesFromBundle(Bundle savedInstanceState) {
if (savedInstanceState != null) {
// Update the value of mRequestingLocationUpdates from the Bundle, and
// make sure that the Start Updates and Stop Updates buttons are
// correctly enabled or disabled.
if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
REQUESTING_LOCATION_UPDATES_KEY);
setButtonsEnabledState();
}
// Update the value of mCurrentLocation from the Bundle and update the
// UI to show the correct latitude and longitude.
if (savedInstanceState.keySet().contains(LOCATION_KEY)) {
// Since LOCATION_KEY was found in the Bundle, we can be sure that
// mCurrentLocationis not null.
mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);
}
// Update the value of mLastUpdateTime from the Bundle and update the UI.
if (savedInstanceState.keySet().contains(LAST_UPDATED_TIME_STRING_KEY)) {
mLastUpdateTime = savedInstanceState.getString(
LAST_UPDATED_TIME_STRING_KEY);
}
updateUI();
}
}