简介
实际上Android应用可以通过GPS来获取定位信息。上一章中我们已经介绍了如何通过GPS来获取定位信息,因此如果把前面介绍的GPS定位与本章中Google Map结合起来,就可以非常方便地开发出GPS导航应用。 10.6.1 随着Location的变化,Google Map定位到不同的位置
示例:将Google Map和Location结合起来,实现的具体功能是:随着Location的变化,Google Map定位到不同的位置
第一步:修改主布局文件的代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.google.android.maps.MapView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/mapView"
android:clickable="true"
android:apiKey="0ZunUBGNC7PX6f_EXkmsJJA1436uoJ3dAsWhXuw" />
</LinearLayout>
第二步:修改MainActivity类代码如下所示:
public class MainActivity extends MapActivity {
MapView mapView = null;
MapController controller = null;
GeoPoint point = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.mapView);
mapView.setClickable(true);
mapView.setBuiltInZoomControls(true);
int latitudeE6 = (int) 34.752014421190424 * 1000000;
int longitudeE6 = (int) 113.66632941527462 * 1000000;
point = new GeoPoint(latitudeE6, longitudeE6);
controller = mapView.getController();
controller.animateTo(point);
controller.setZoom(mapView.getZoomLevel()-1);
controller.setCenter(point);
LocationManager manager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
1200, 0, listener);
}
LocationListener listener = new LocationListener() {
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
public void onLocationChanged(Location location) { //修改定位点的坐标值
int latitudeE6 = (int) location.getLatitude() * 1000000;
int longitudeE6 = (int) location.getLongitude()* 1000000;
point = new GeoPoint(latitudeE6, longitudeE6);
controller.animateTo(point);
controller.setZoom(mapView.getZoomLevel()+1);
}
};
@Override
protected boolean isRouteDisplayed() {
return false;
}
}
刚启动时程序运行效果如下图所示:
在Emulator Controler中输入不同的经纬度,会定位到不同的位置:
输入不同经纬度后程序的运行效果所示:
示例:开发一个非常简单的GPS导航系统,要求该应用程序每隔30秒获取一次GPS定位数据,当程序得到 GPS定位信息之后,程序就把Google Map定位到该位置,这样就可以在地图上实时地跟踪设备的移动位置。
本程序的界面非常简单,只提供一个MapView来显示设备在地图上的位置,具体代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.google.android.maps.MapView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/mapView"
android:clickable="true"
android:apiKey="0ZunUBGNC7PX6f_EXkmsJJA1436uoJ3dAsWhXuw" />
</LinearLayout>
然后自定义图层类,最终代码如下所示:
class PosOverLay extends Overlay {
Bitmap posBitmap; // 定义该PosOverLay所绘制的位图
GeoPoint point; // 定义该PosOverLay绘制位图的位置
public PosOverLay(GeoPoint point, Bitmap posBitmap) {
this.point = point;
this.posBitmap = posBitmap;
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if (!shadow) {
Projection proj = mapView.getProjection();// 获取MapView的Projection对象
Point p = new Point();
proj.toPixels(point, p); // 将真实的地理坐标转化为屏幕上的坐标
// 在指定位置绘制图片
canvas.drawBitmap(posBitmap, p.x - posBitmap.getWidth() / 2,
p.y - posBitmap.getHeight(), null);
}
}
}
最后修改MainActivity类的代码如下所示:
public class MainActivity extends MapActivity {
MapView mapView;
MapController controller;
Bitmap posBitmap;
LocationManager locManager;
@Override
protected void onCreate(Bundle status) {
super.onCreate(status);
setContentView(R.layout.gps);
posBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tool);
mapView = (MapView) findViewById(R.id.mapView); // 获得界面上MapView对象
mapView.setBuiltInZoomControls(true); // 设置显示放大、缩小的按钮
controller = mapView.getController();// 创建MapController对象
// 获取LocationManager对象
locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// 设置每30秒获取一次GPS的定位信息
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 10,
new LocationListener() {
@Override// 当GPS定位信息发生改变时,更新位置
public void onLocationChanged(Location location) {
updateMapView(location);
}
@Override
public void onProviderDisabled(String provider) {
}
@Override// 当GPS LocationProvider可用时,更新位置
public void onProviderEnabled(String provider) {
updateMapView(locManager.getLastKnownLocation(provider));
}
@Override
public void onStatusChanged(String provider,int status,Bundle extras) {
}
});
}
@Override
protected boolean isRouteDisplayed() {
return true;
}
// 根据Location来更新MapView
private void updateMapView(Location location) {
// 将Location对象中的经、纬度信息包装成GeoPoint对象
GeoPoint gp = new GeoPoint((int) (location.getLatitude() * 1E6),
(int) (location.getLongitude() * 1E6));
mapView.displayZoomControls(true); // 设置显示放大缩小按钮
controller.animateTo(gp); // 将地图移动到指定的地理位置
List<Overlay> ol = mapView.getOverlays();// 获得MapView上原有的Overlay对象
ol.clear();// 清除原有的Overlay对象
ol.add(new PosOverLay(gp, posBitmap)); // 添加一个新的OverLay对象
}
}
因为本程序需要使用Google Map,因此需要在功能清单文件中添加如下权限:
<!-开启访问internet的权限 ->
<uses-permission android:name="android.permission.INTERNET" />
<!-用于获取”精确的”位置数据,比如GPS数据->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
运行程序,打开Emulator Controller,更换不同的经纬度,发送数据,程序运行结果如下图所示: