关于百度地图的申请,获得密钥在这里就不多说了。
创建简单地图
进行地图选点
定位是需要一些设置的,定位有三种定位方式,高精度,低功耗,仅设备;其中高精度是网络加上gps进行定位,而低功耗是使用网络进行定位。要定位首先要将LocationClient实例化,然后设置监听,设置配置信息。
获取路线
导航
创建简单的地图就是将百度的地图界面显示在手机上,首先要创建一个android工程,然后将百度SDK的库导入进去,
BaiduLBS_Android.jar 百度地图基本jar包
BaiduNaviSDK_2.0.jar 百度地图导航的SDK jar包
locSDK_6.03.jar 百度地图定位的SDK jar包
除此之外还要将一些so库文件导入,因为一些处理是使用jni的方法:
libapp_BaiduMapApplib_v2_1_2.so 百度地图基本的库
liblocSDK6.so
libvi_voslib.so
在之后我们还要为工程添加权限,
<uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE">
</uses-permission>
<uses-permissionandroid:name="android.permission.INTERNET">
</uses-permission>
<uses-permissionandroid:name="com.android.launcher.permission.READ_SETTINGS"/>
<uses-permissionandroid:name="android.permission.WAKE_LOCK">
</uses-permission>
<uses-permissionandroid:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- SDK1.5需要android.permission.GET_TASKS权限判断本程序是否为当前运行的应用? -->
<uses-permissionandroid:name="android.permission.GET_TASKS"/>
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE">
</uses-permission>
<uses-permissionandroid:name="android.permission.WRITE_SETTINGS"/>
<!-- 这个权限用于进行网络定位-->
<uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!-- 这个权限用于访问GPS定位-->
<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permissionandroid:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!-- 用于读取手机当前的状态-->
<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!-- 访问网络,网络定位需要上网-->
<uses-permissionandroid:name="android.permission.INTERNET"/>
<!-- SD卡读取权限,用户写入离线定位数据-->
<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<!--允许应用读取低级别的系统日志文件 -->
<uses-permissionandroid:name="android.permission.READ_LOGS"></uses-permission>
将这些权限放入Mainfest文件中就可以了,在使用百度地图的时候,可以通过xml文件来构建自己想要的界面,地图的控件是com.baidu.mapapi.map.MapView;
<com.baidu.mapapi.map.MapView
android:id="@+id/mv_map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true">
</com.baidu.mapapi.map.MapView>
但是值得注意的是,在oncreate中调用setContentView之前一定要调用SDKInitializer.initialize(getApplicationContext());// 初始化,在使用百度地图控件之前,包括xml中使用,不然就会报错。
@Override
protected void onPause() {
super.onPause();
// activity 暂停时同时暂停地图控件
mMapView.onPause();
}
@Override
protected void onResume(){
super.onResume();
// activity 恢复时同时恢复地图控件
mMapView.onResume();
}
这样的话你运行程序就可以得到一个百度地图的界面。
进行地图选点功能就是响应地图的点击时间(这个你可以是单机,双击,长按等事件),这里我用的是单击时间,在新版本中没有BMapManager这个类,在新版本中使用BaiduMap这个来进行地图的管理,BaiduMapmBaiduMap = mMapView.getMap();
之后将mBaiduMap.setOnMapClickListener(this); 本类实现接口OnMapClickListener,接口中实现:
@Override
public voidonMapClick(LatLng latlng) {//点击事件,直接获取的是所点的经纬度
//用来将地图定位到所点的地方
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(latlng));
mBaiduMap.clear();//清空地图上的overly
//ooA是一个Marker对象,这是想地图上添加标注bdA是一个图片的处理,是bdA = BitmapDescriptorFactory.fromResource(R.drawable.icon_marka);// 设置覆盖物的标签
ooA = new MarkerOptions().position(latlng).icon(bdA).zIndex(9)
.draggable(true);
mBaiduMap.addOverlay(ooA);//店家到地图上
selectedLalng =latlng;//设置地理编码检索监听者
geoCoder.reverseGeoCode(newReverseGeoCodeOption().location(latlng));//要进行反地址编码,来通过经纬度来获取地址描述
}
@Override
public booleanonMapPoiClick(MapPoi poi) {//点击地图上的点,就是可以看见的点
System.out.println(poi.getName());
return true;
}
有地址编码和反地址编码,地址编码是将实际的地址信息(字符串)转化成经纬度;反地址编码是将经纬度转化成地址信息。需要设置监听,监听函数如下:
geoCoder = GeoCoder.newInstance();
geoCoder.setOnGetGeoCodeResultListener(listener);
OnGetGeoCoderResultListener listener = newOnGetGeoCoderResultListener() {
// 反地理编码查询结果回调函数
@Override
public voidonGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
if (result ==null){//没有检测到结果
Toast.makeText(MainActivity.this,"抱歉,未能找到结果",
Toast.LENGTH_LONG).show();
}
/**自定义弹出窗口操作*/
}
// 地理编码查询结果回调函数
@Override
public voidonGetGeoCodeResult(GeoCodeResult result) {
if (result ==null || result.error !=SearchResult.ERRORNO.NO_ERROR){
Return;
} else {
/**获取相关线路*/
}
}
};
自定义弹出窗图层可以在xml中将布局写好,然后通inflat,如下:
View view = LayoutInflater.from(getApplicationContext()).inflate(
R.layout.item_info_window,null);
InfoWindowmInfoWindow = newInfoWindow(view, result.getLocation(),
-80);
mBaiduMap.showInfoWindow(mInfoWindow);
这样你就可以自定义弹出框了,可以随意设置, view就是显示layout,第二个参数是经纬度,第三个参数是y轴偏移量。-80就是向上偏移80.
进行定位
private LocationModetempMode = LocationMode.Battery_Saving;//设置为低功耗
localClient = new LocationClient(this.getApplicationContext());
private voidsetOpration() {
LocationClientOption option = new LocationClientOption();
option.setLocationMode(tempMode);//默认高精度,高精度,低功耗,仅设备
option.setCoorType("bd09ll");//默认gcj02,设置返回的定位结果为经纬度
int span = 1000;//定位延迟
option.setScanSpan(span);// 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
option.setOpenGps(false);//可选,默认false,设置是否使用gps
option.setIgnoreKillProcess(true);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
location.setLocOption(option);//设置
}
//设置监听
public classMyLocationListener implementsBDLocationListener {
//这里之获取经纬度和地址信息
@Override
public voidonReceiveLocation(BDLocation location) {
activity.sendBroadcast(new Intent(Contact.ACTION_LOCATION)
.putExtra("la",location.getLatitude()).putExtra("lo",
location.getLongitude()).putExtra("addr", location.getAddrStr()));
}
}
进行这些之后就可以通过localClient.start()和localClient.stop();来控制定位的开始结束。
获取百度地图的规划后的路线,百度可以根据选择规划驾车,公交,步行的路径规划。
private RoutePlanSearchsearh=RoutePlanSearch.newInstance();
searh.setOnGetRoutePlanResultListener(this);
这里就需要实现OnGetRoutePlanResultListener接口,实现以下接口:
// 步行路线
public void onGetWalkingRouteResult(WalkingRouteResultwResult) {
if (wResult ==null || wResult.error !=SearchResult.ERRORNO.NO_ERROR){//相关错误处理}
if (wResult.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
//相关错误处理
}
//获取第一调路线
routeW =(RouteLine<WalkingStep>) wResult.getRouteLines().get(0);
WalkingRouteOverlayoverlay = newWalkingRouteOverlay(mBaiduMap);
//设置路线覆盖物
mBaiduMap.setOnMarkerClickListener(overlay);
//设置相关路线信息
overlay.setData(wResult.getRouteLines().get(0))
overlay.addToMap();
overlay.zoomToSpan();
}
@Override
// 公交路线与步行路线处理相似
public void onGetTransitRouteResult(TransitRouteResulttResult) {
}
@Override
// 驾车路线与步行路线处理相似
public void onGetDrivingRouteResult(DrivingRouteResultdResult) {
}
首先要进行初始化,百度提供了自己的导航页。
在使用之前我们要把<serviceandroid:name="com.baidu.location.f"android:enabled="true"android:process=":remote"></service>添加在mainfest文件中。
将libapp_BaiduNaviApplib.so
libapp_BaiduVIlib.so
libBaiduMapSDK_v3_5_0_15.so
libbd_etts.so
libbds.so
libBDSpeechDecoder_V1.so
libcurl.so
libgnustl_shared.so
libvi_voslib.so 导入armeabi或armeabi-v7a。
将BaiduNaviSDK_Resource_2.0.png和channel拷入assets文件夹中
mSDCardPath 是获得当前的工作目录
private void initNavi(){
BaiduNaviManager.getInstance().setNativeLibraryPath(
mSDCardPath + "/BaiduNaviSDK_SO");//这个是必须要的
BaiduNaviManager.getInstance().init(this,mSDCardPath, APP_FOLDER_NAME,//APP名称
new NaviInitListener() {
@Override
publicvoidonAuthResult(int status,String msg) {
if (0 == status) //成功
else//失败
}
@Override
publicvoidinitSuccess() {//成功}
@Override
publicvoid initStart(){//开始}
@Override
publicvoidinitFailed() {失败}
}, null/*mTTSCallback */语音);
}
设置导航信息,(起始地和目的地)
private voidrouteplanToNavi(CoordinateType coType, LatLng st, LatLng ed ) {
BNRoutePlanNode sNode= null;
BNRoutePlanNode eNode= null;
switch (coType) {
case WGS84: {//参数分别是经纬度,地方名称,地方详细描述,类型
sNode = new BNRoutePlanNode(st.longitude, st.latitude ,null, null,coType);
eNode = new BNRoutePlanNode(ed.longitude, ed.latitude ,null, null,coType);
break;
}
}
//第一个是主activity,第二个参数是路径节点列表,第三个参数偏好、参考RoutePlanPreference,第四个参数是否使用真实gps进行导航,第五个参数导航监听
if (sNode !=null &&eNode != null) {
List<BNRoutePlanNode>list = newArrayList<BNRoutePlanNode>();
list.add(sNode);
list.add(eNode);
BaiduNaviManager.getInstance().launchNavigator(this, list, 1,true,new MyoutePlanListener( sNode ));
}
}
导航监听如下:
class MyoutePlanListenerimplements RoutePlanListener {
private BNRoutePlanNodemBNRoutePlanNode = null;//起始点信息
public MyoutePlanListener(BNRoutePlanNode node){
mBNRoutePlanNode = node;
}
@Override
public voidonJumpToNavigator() {
//开启百度自己的导航页面
Intent intent = new Intent(MainActivity.this,NaviManafer.class);
Bundle bundle = new Bundle();
bundle.putSerializable(ROUTE_PLAN_NODE, (BNRoutePlanNode)mBNRoutePlanNode);
intent.putExtras(bundle);
startActivity(intent);
}
@Override
public voidonRoutePlanFailed() {
//路径规划失败
}
}
在这之后在导航过程页面,将导航过程页面构造
View view = BNRouteGuideManager.getInstance().onCreate(this,new OnNavigationListener() {
@Override
public voidonNaviGuideEnd() {
finish();
}
@Override
public voidnotifyOtherAction(int actionType,int arg1,int arg2, Object obj) { }
});
setContentView(view);
之后根据起始节点将这次导航的layout加入到路线规划管理智中。
private voidaddCustomizedLayerItems() {
List<CustomizedLayerItem>items = new ArrayList<CustomizedLayerItem>();
CustomizedLayerItemitem1 = null;
if (mBNRoutePlanNode !=null) {
item1 = new CustomizedLayerItem(mBNRoutePlanNode.getLongitude(),mBNRoutePlanNode.getLatitude(),
mBNRoutePlanNode.getCoordinateType(), getResources().getDrawable(R.drawable.ic_launcher),//自定义图层
CustomizedLayerItem.ALIGN_CENTER);
items.add(item1); BNRouteGuideManager.getInstance().setCustomizedLayerItems(items);
}
BNRouteGuideManager.getInstance().showCustomizedLayer(true);
//显示自定义图层
}