Andriod定位实现(Google)

基于位置的服务简称 LBS,主要的工作原理就是利用无线电通讯网络或 GPS 等定位方式来确定出移动设备所在的位置.
  定位过程如下:

1.LocationManager的使用

  要想使用 LocationManager就必须要先获取到它的实例, 我们可以调用 Context
的 getSystemService()方法获取到。getSystemService()方法接收一个字符串参数用于确定获取
系统的哪个服务, 这里传入 Context.LOCATION_SERVICE 即可。 因此, 获取 LocationManager
的实例就可以写成:
LocationManager locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
接着我们需要选择一个位置提供器来确定设备当前的位置。Android 中一般有三种位置
提供器可供选择,GPS_PROVIDER、NETWORK_PROVIDER 和 PASSIVE_PROVIDER。其
中前两种使用的比较多,分别表示使用 GPS 定位和使用网络定位。这两种定位方式各有特
点,GPS 定位的精准度比较高,但是非常耗电,而网络定位的精准度稍差,但耗电量比较少。
我们应该根据自己的实际情况来选择使用哪一种位置提供器, 当位置精度要求非常高的时候,
最好使用 GPS_PROVIDER,而一般情况下,使用 NETWORK_PROVIDER 会更加得划算。
将选择好的位置提供器传入到 getLastKnownLocation()方法中, 就可以得到一个 Location
对象,如下所示:
String provider = LocationManager.NETWORK_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
这个 Location 对象中包含了经度、纬度、海拔等一系列的位置信息,然后从中取出我们
所关心的那部分数据即可。
如果有些时候你想让定位的精度尽量高一些,但又不确定 GPS 定位的功能是否已经启
用,这个时候就可以先判断一下有哪些位置提供器可用,如下所示:
List<String> providerList = locationManager.getProviders(true);
可以看到,getProviders()方法接收一个布尔型参数,传入 true 就表示只有启用的位置提
供器才会被返回。之后再从 providerList 中判断是否包含 GPS 定位的功能就行了。
LocationManager 还提供了一个 requestLocationUpdates()方法,
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10,
new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle
extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onLocationChanged(Location location) {
}
});
这里 requestLocationUpdates()方法接收四个参数,第一个参数是位置提供器的类型,第
二个参数是监听位置变化的时间间隔,以毫秒为单位,第三个参数是监听位置变化的距离间
隔,以米为单位,第四个参数则是 LocationListener监听器。这样的话,LocationManager每隔
5 秒钟会检测一下位置的变化情况,当移动距离超过 10 米的时候,就会调用 LocationListener
的 onLocationChanged()方法,并把新的位置信息作为参数传入。

另外,获取设备当前的位置信息也是要声明权限的,因此还需要修改 AndroidManifest.xml
中的代码,<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

反向地理编码,看得懂的位置信息
Geocoding API 的用法
GeocodingAPI 的工作原理并不神秘,其实就是利用HTTP 协议。
在手机端我们可以向谷歌的服务器发起一条 HTTP 请求,并将经纬度的值作为参数一同传递
过去,然后服务器会帮我们将这个经纬值转换成看得懂的位置信息,再将这些信息返回给手
机端,最后手机端去解析服务器返回的信息,并进行处理就可以了。
Geocoding API 中规定了很多接口,其中反向地理编码的接口如下:
http://maps.googleapis.com/maps/api/geocode/json? latlng=40.714224,- 73.961452&sensor=true_or_false

private void showLocation(final Location location) {
new Thread(new Runnable() {
@Override
public void run() {
try {
// 组装反向地理编码的接口地址
StringBuilder url = new StringBuilder();
url.append("http://maps.googleapis.com/maps/api/geocode/json?latlng=");
url.append(location.getLatitude()).append(",")
url.append(location.getLongitude());
url.append("&sensor=false");
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url.toString());
// 在请求消息头中指定语言,保证服务器会返回中文数据
httpGet.addHeader("Accept-Language", "zh-CN");
HttpResponse httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity,
"utf-8");
JSONObject jsonObject = new JSONObject(response);
// 获取results节点下的位置信息
JSONArray resultArray = jsonObject.getJSONArray
("results");
if (resultArray.length() > 0) {
JSONObject subObject = resultArray.
getJSONObject(0);
// 取出格式化后的位置信息
第一行代码——Android
420
String address = subObject.getString
("formatted_address");
Message message = new Message();
message.what = SHOW_LOCATION;
message.obj = address;
handler.sendMessage(message);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_LOCATION:
String currentPosition = (String) msg.obj;
positionTextView.setText(currentPosition);
break;
default:
break;
}
}
};
观察 showLocation()方法,由于我们要在这里发起网络请求,因此必须开启一个子线程。
在子线程中首先是通过 StringBuilder 组装了一个反向地理编码接口地址的字符串,然后使用
HttpClient 去请求这个地址就好了。注意在 HttpGet 中我们还添加了一个消息头,消息头中将
语言类型指定为简体中文,不然服务器会默认返回英文的位置信息。

posted on 2016-04-09 16:21  Day_to_Day  阅读(430)  评论(0编辑  收藏  举报

导航