您的位置:首页 > 移动开发 > Android开发

Android学习之LBS

2015-11-17 20:41 507 查看
流程简述:

1)获取locationManager实例

LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
2)选择一个位置提供器来确定设备当前的位置

这里可选择GPS_PROVIDER、NETWORK_PROVIDER和
PASSIVE_PROVIDER三种定位方式

3)获取location对象,取出所需数据解析即可

String provider = LocationManager.NETWORK_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);


查看可用的位置提供器

List<String> providerList = locationManager.getProviders(true);
getProviders()方法接收一个布尔型参数,传入true
就表示只有启用的位置提供器才会被返回

获取用户的最新位置

这里需要用的一个新的方法: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) {
}
});


参数:位置提供器的类型、更新时间间隔、更新距离间隔、位置监听器

此时LocationManager每隔5秒钟会检测一下位置的变化情况,当移动距离超过
10米的时候,就会调用
LocationListener的onLocationChanged()方法,并把新的位置信息作为参数传入。

一个获取经纬度的程序示例(这里的布局只需要一个TextView即可)

public class MainActivity extends Activity {
private TextView positionTextView;
private LocationManager locationManager;
private String provider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
positionTextView = (TextView) findViewById(R.id.position_text_view);
locationManager = (LocationManager) getSystemService(Context.
LOCATION_SERVICE);
// 获取所有可用的位置提供器
List<String> providerList = locationManager.getProviders(true);
if (providerList.contains(LocationManager.GPS_PROVIDER)) {
provider = LocationManager.GPS_PROVIDER;
} else if (providerList.contains(LocationManager.NETWORK_PROVIDER)) {
provider = LocationManager.NETWORK_PROVIDER;
} else {
// 当没有可用的位置提供器时,弹出Toast提示用户
Toast.makeText(this, "No location provider to use",
Toast.LENGTH_SHORT).show();
return;
}
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
// 显示当前设备的位置信息
showLocation(location);
}
locationManager.requestLocationUpdates(provider, 5000, 1,
locationListener);
}
protected void onDestroy() {
super.onDestroy();
if (locationManager != null) {
// 关闭程序时将监听器移除
locationManager.removeUpdates(locationListener);
}
}
LocationListener locationListener = 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) {
// 更新当前设备的位置信息
showLocation(location);
}
};
private void showLocation(Location location) {
String currentPosition = "latitude is " + location.getLatitude() + "\n"
+ "longitude is " + location.getLongitude();
positionTextView.setText(currentPosition);
}
}


权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
以上代码即可实现实时监听位置的经纬度变化信息

为了能将经纬度转换为我们易于理解的位置信息,这里引入反向地理编码。
由于Android自带的GeoCoder不够稳定,这里使用Google推出的Geocoding API,流程就是利用http将经纬度数据传输给google服务器,之后接收其返回的数据并解析为易于理解的位置数据即可。
Google 反向地理编码接口(需要翻墙):
http://maps.googleapis.com/maps/api/geocode/jsonlatlng=40.714224,-73.961452&sensor=true_or_false

这里json表示希望返回json类型的数据,latlng表示需要解析的经纬度,sensor则表示这个http请求是否来自某一设备的传感器。
该例返回的json格式数据为
"formatted_address" : "277 Bedford Avenue,布鲁克林纽约州
11211美国"
解析完整代码:

public class MainActivity extends Activity {
public static final int SHOW_LOCATION = 0;
……
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);
// 取出格式化后的位置信息
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;
}
}
};
}


这样我们就可以在TextView中看到详细的地址,以上代码主要运用了httpClient传输数据和JSON数据解析,此外,注意在AndroidManifest中添加Internet权限。

此外,推荐一个网站,https://www.juhe.cn/,这里提供众多的API接口可以帮助你实现诸多服务性功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: