在完成HelloMap后,接来完成的重要功能是如何定位当前位置和如何一键返回。效果图如下:
这里的控件就是一个ImageView,自己去百度一个好看的图片就可以了。
一 定位当前位置和自定义控件返回
1.官方技术文档
可以先点击百度地图定位技术文档,仔细看一下相关函数调用方法。对于新手开发和用最新版sdk的帮助很大。我们之前就是按照网上之前旧版本开发的,直接看直接去用踩过很多坑。看完官方的技术文档在看下面的activity程序介绍。
2.个人开发过程
看一下我的MapActivity程序,相关的注释已给出。
import java.util.List;
import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.baidu.location.Poi;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.yanis.yc_ui_fragment_tabhost.R.id;
public class MapActivity extends Activity {
private BitmapDescriptor currentMarker = null;
private MyLocationConfiguration.LocationMode currentMode;
private ImageView iv_location;
MapView mMapView = null;
public static final String TAG="mian";
StringBuffer sb = new StringBuffer(256);
public StringBuilder builder=new StringBuilder();
boolean isOpenLocation=false;
private BaiduMap mBaiduMap;
public LocationClient mLocationClient = null;
public BDLocationListener myListener = new MyLocationListener();
private boolean isFirstLocation = true;
private double lat;
private double lon;
private BDLocation mCurrentLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.app_map);
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
// 删除百度地图LoGo
mMapView.removeViewAt(1);
mLocationClient = new LocationClient(getApplicationContext()); //声明LocationClient类
mLocationClient.registerLocationListener( myListener ); //注册监听函数
initView();//ImageView初始化
initLocation();//配置定位SDK参数
mLocationClient.start();
mBaiduMap.setMyLocationEnabled(true);
currentMode = MyLocationConfiguration.LocationMode.NORMAL;//NORMAL为正常模式 FOLLOWING为跟随模式 COMPASS为罗盘模式
mBaiduMap.setMyLocationConfigeration(new MyLocationConfiguration(
currentMode, true, currentMarker));
}
private void initView() {
iv_location = (ImageView) findViewById(R.id.iv_location);
iv_location.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentLocation != null) {
LatLng latLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latLng);
mBaiduMap.animateMapStatus(mapStatusUpdate, 1000);
}
}
});
}
private void initLocation(){
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
int span=0;
option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
option.setOpenGps(true);//可选,默认false,设置是否使用gps
option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
mLocationClient.setLocOption(option);
}
public class MyLocationListener implements BDLocationListener {
private float radius;
@Override
public void onReceiveLocation(BDLocation location) {
StringBuffer sb = new StringBuffer(256);
// sb.append("time : ");
// sb.append(location.getTime());
// sb.append("\nerror code : ");
// sb.append(location.getLocType());
// sb.append("\nlatitude : ");
// sb.append(location.getLatitude());
// sb.append("\nlontitude : ");
// sb.append(location.getLongitude());
// sb.append("\nradius : ");
// sb.append(location.getRadius());
if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
sb.append("\nspeed : ");
sb.append(location.getSpeed());// 单位:公里每小时
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber());
sb.append("\nheight : ");
sb.append(location.getAltitude());// 单位:米
sb.append("\ndirection : ");
sb.append(location.getDirection());// 单位度
sb.append("\naddr : ");
sb.append(location.getAddrStr());
sb.append("\ndescribe : ");
sb.append("gps定位成功");
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
// sb.append("\naddr : ");
sb.append(location.getAddrStr());
//运营商信息
// sb.append("\noperationers : ");
// sb.append(location.getOperators());
// sb.append("\ndescribe : ");
// sb.append("网络定位成功");
} else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
sb.append("\ndescribe : ");
sb.append("离线定位成功,离线定位结果也是有效的");
} else if (location.getLocType() == BDLocation.TypeServerError) {
sb.append("\ndescribe : ");
sb.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
} else if (location.getLocType() == BDLocation.TypeNetWorkException) {
sb.append("\ndescribe : ");
sb.append("网络不同导致定位失败,请检查网络是否通畅");
} else if (location.getLocType() == BDLocation.TypeCriteriaException) {
sb.append("\ndescribe : ");
sb.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
}
sb.append("\nlocationdescribe : ");
sb.append(location.getLocationDescribe());// 位置语义化信息
List<Poi> list = location.getPoiList();// POI数据
if (list != null) {
sb.append("\npoilist size = : ");
sb.append(list.size());
for (Poi p : list) {
sb.append("\npoi= : ");
sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
}
}
mCurrentLocation = location;
radius = location.getRadius();
lat = location.getLatitude(); //当前的经纬度
lon = location.getLongitude();
if(isFirstLocation){
// 构造定位数据
MyLocationData locData = new MyLocationData.Builder()
.accuracy(radius)
.latitude(lat)
.longitude(lon)
.build();
// 设置定位数据
mBaiduMap.setMyLocationData(locData);
LatLng ll = new LatLng(lat, lon);
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(msu);
// //定义地图状态
MapStatus mMapStatus = new MapStatus.Builder()
.target(ll)
.zoom(18) //自定义定位后地图显示的缩放比例
.build();
//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
//改变地图状态
mBaiduMap.setMapStatus(mMapStatusUpdate);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}
}
在运行程序之前,我们还必须在AndroidManifest.xml进行相关配置和权限的声明
在application标签中声明定位service组件
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote" >
附上网络上关于百度地图定位原理
官方的简介为http://developer.baidu.com/announcement/408
使用百度Android定位SDK必须注册GPS和网络使用权限。定位SDK采用GPS、基站、Wi-Fi信号进行定位。当应用程序向定位SDK发起定位请求时,定位SDK会根据应用的定位因素(GPS、基站、Wi-Fi信号)的实际情况(如是否开启GPS、是否连接网络、是否有信号等)来生成相应定位依据进行定位。
用户可以设置满足自身需求的定位依据:
若用户设置GPS优先,则优先使用GPS进行定位,如果GPS定位未打开或者没有可用位置信息,且网络连接正常,定位SDK则会返回网络定位(即Wi-Fi与基站)的最优结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。