12.3.2 位置

    由于访问这些服务的移动设备的位置可能会发生改变,因此利用位置作为请求的一部分可能会很有趣。在一个地方搜索Flickr上的“waterfront”图像与随后从另一个地方进行搜索将产生不同的结果。

    Android提供了LocationManager类,可以使用它来查找并跟踪应用程序的位置变化。

    下面是一个简单的代码片段,它演示了如何利用LocationManager以及如何监听位置的更新。

 1 package com.nthm.androidtestActivity;
 2 
 3 import com.nthm.androidtest.R;
 4 import android.app.Activity;
 5 import android.content.Context;
 6 import android.location.Location;
 7 import android.location.LocationListener;
 8 import android.location.LocationManager;
 9 import android.location.LocationProvider;
10 import android.os.Bundle;
11 import android.widget.TextView;

    为了从LocationManager接收位置更新,活动将实现LocationListener。

1 public class LocationTracking extends Activity implements LocationListener {
2     private LocationManager lm;
3     private TextView tv;
4     @Override
5     protected void onCreate(Bundle savedInstanceState) {
6         super.onCreate(savedInstanceState);
7         setContentView(R.layout.locationtracking);
8         tv=(TextView) findViewById(R.id.location);

    可以采用Context中可用的getSystemService方法得到一个LocationManager示例由于活动时Context的一个子类,因此他对我们可用。

1         lm=(LocationManager) getSystemService(Context.LOCATION_SERVICE);

    LocationManager允许指定是否希望LocationListener(在此事例中是当前的活动)获得位置相关变化的通知。通过将其做为最后一个参数传递给requestLocationUpdates方法,可以将活动注册为LocationListener。

    方法的第一个参数是想要使用的位置提供器。两个可用的位置提供器定义为在LocationManager类中的常量。此处使用的是NETWORK_PROVIDER,其利用网络服务(如手机信号塔的位置和WiFi访问点的位置确定。另一个可用的位置提供器是GPS_PROVIDER,其利用GPS(Global Positioning Statellites,全球定位卫星)来提供位置信息。NETWORK_PROVIDE通常会更快,可能其位置查找不太精确。GPS可能需要大量的时间从卫星获得信号,而且不能再所有的室内或者天空不太清晰的地区工作(例如马哈顿中城)。

    第二个参数是系统在“位置更改”通知之间等待的最少时间,通过一个表示毫秒数的长整数来指定该时间。在这里使用6000毫秒或1分钟。

    第三个参数是在发出一个“位置更改”通知之前位置需要改变的距离量,可以通过一个表示米的浮点数来指定该距离量。在这里使用5米。

1         lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 6000, 5.0f, this);
2     }

    当使用LocationManager时,尤其是当使用GPS作为位置提供器时,如果应用程序不再位于前台,那么可能需要谨慎的停止位置更新。因为这将节省电池的电量。为此,可以重写活动中的onPause或onStop方法,并调用LocationManager对象上的removeUpdates方法。

1     @Override
2     protected void onPause() {
3         super.onPause();
4         lm.removeUpdates(this);
5     }

    每当位置发生改变时,其更改大于在requestLocationUpdates方法中指定的距离和时间参数时,将会在注册的LocationListener上调用onLocationChanged方法,并传入一个Location对象。

    传入的Location对象具有可用于获取纬度(getLatitude)、经度(getLongitude)、海拔以及更多信息的方法。

1     @Override
2     public void onLocationChanged(Location location) {
3         tv.setText(location.getLatitude()+" "+location.getLongitude());
4     }

    如果用户禁用了正被监听的提供器,那么调用注册的LocationListener上的onProviderDisabled方法。

1     @Override
2     public void onProviderDisabled(String provider) {
3 
4     }

    如果用户启用了正在被监听的提供器,那么调用注册的LocationListener上的onProviderEnabled方法。

1     @Override
2     public void onProviderEnabled(String provider) {
3 
4     }

    最后,如果位置提供器的状态发生了更改,那么调用注册的LocationListener上的onStatusChanged方法。在LocationProvider上可以使用3个常量来测试status变量,以明确发生了何种变化。他们是;AVAILABLE,如果提供器在经过一段时间不可用之后变得可用,那么将调用它;TEMPORARILY_UNAVAILABLE,正如其名所暗示的那样,提供器暂时不能用,因为它无法获取当前位置;最后是OUT_OF_SERVICE,这意味着提供器可能由于失去连接或信号而无法使用。

 1     @Override
 2     public void onStatusChanged(String provider, int status, Bundle extras) {
 3           if(status==LocationProvider.AVAILABLE){
 4               
 5           }else if(status==LocationProvider.TEMPORARILY_UNAVAILABLE){
 6               
 7           }else if(status==LocationProvider.OUT_OF_SERVICE){
 8               
 9           }
10     }
11 }

    下面是上述活动所需的布局XML。

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical"
 5     >
 6  <TextView 
 7      android:id="@+id/location"
 8      android:text="Status"
 9      android:layout_width="fill_parent"
10      android:layout_height="wrap_content"
11      android:textSize="35dip"></TextView>
12   
13 </LinearLayout>

    访问位置必须有请求的权限,所以需要将以下uses-permission标记添加到AndroidManifest.xml文件。注意以下标记用于LocationManager.NETWORK_PROVIDER提供器,它将提供一个粗略的位置。

1     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

    如果有兴趣以GPS使用更精确的位置,那么需要使用ACCESS_FINE_LOCATION权限。

1     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

 

posted on 2014-09-11 10:48  宁静致远,一览众山小  阅读(420)  评论(0编辑  收藏  举报

导航