百度地图最新版本sdk使用系列(七)-实现定位,poi搜索和导航

定位和搜索的核心类请看该系列的前面几篇文章,导航的核心类是BaiduNaviManager,该类的核心方法包括:
initEngine初始化导航引擎
createNMapView创建NMapView
launchNavigator启动导航
核心接口是OnStartNavigationListener(),启动导航的监听器,跳转到基于sdk自定义的[导航页]
另外需新建一个activity,用于实现百度自定义的导航视图.详细代码如下:
"http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.yuneec.yuneecmap.MainActivity" >


    map.MapView
        android:id="@+id/bmapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@id/ll"
        android:clickable="true" />    

    "@+id/ll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

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.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.InfoWindow.OnInfoWindowClickListener;
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.Marker;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.overlayutil.PoiOverlay;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiDetailSearchOption;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.navisdk.BNaviEngineManager.NaviEngineInitListener;
import com.baidu.navisdk.BaiduNaviManager;
import com.baidu.navisdk.BaiduNaviManager.OnStartNavigationListener;
import com.baidu.navisdk.comapi.routeplan.RoutePlanParams.NE_RoutePlan_Mode;

public class MainActivity extends Activity {    
    private static final String TAG = "MainActivity";   

    //导航相关
    private boolean mIsEngineInitSuccess = false;  
    //导航引擎初始化监听
    private NaviEngineInitListener mNaviEngineInitListener = new NaviEngineInitListener() {  
            public void engineInitSuccess() {  
                //导航初始化是异步的,需要一小段时间,以这个标志来识别引擎是否初始化成功,
                //为true时候才能发起导航  
                mIsEngineInitSuccess=true;
            }  
            //引擎初始化开始
            public void engineInitStart() {  
            }  
            //引擎初始化失败
            public void engineInitFail() {  
            }  
        };  
    private String getSdcardDir() {  
            if (Environment.getExternalStorageState().equalsIgnoreCase(  
                    Environment.MEDIA_MOUNTED)) {  
                return Environment.getExternalStorageDirectory().toString();  
            }  
            return null;  
        }           


    private MapView mMapView;// 地图视图
    private BaiduMap mBaiduMap;// 地图控制器 setMapStatus(mMapStatusUpdate);
    private MapStatus mMapStatus;// 地图当前状态
    private MapStatusUpdate mMapStatusUpdate;// 地图将要变化成的状态
    private Button btn_location;// 定位button
    private Button btn_search;// 搜索button
    private Button btn_navi;//导航button

    public LocationClient mLocationClient = null;// 定位的核心类:LocationClient
    public BDLocationListener myLocationListener = new MyLocationListener();// 定位的回调接口
    private LatLng mCurrentLatLng;// 当前经纬度坐标
    private double latitude;//纬度
    private double longitude;//经度

    private PoiSearch mPoiSearch;// poi检索核心类
    private MySearchResultListener mySearchResultListener;// poi检索核心接口


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 在使用SDK各组件之前初始化context信息,传入ApplicationContext
        // 该方法要在setContentView方法之前实现
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        init();

        btn_search.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                search();
            }
        });

        btn_location.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                location();
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);// 开启卫星图
                // 获得地图的当前状态的信息
                mMapStatus = new MapStatus.Builder().zoom(15)
                        .target(mCurrentLatLng).build();
                // 设置地图将要变成的状态
                mMapStatusUpdate = MapStatusUpdateFactory
                        .newMapStatus(mMapStatus);
                mBaiduMap.setMapStatus(mMapStatusUpdate);// 设置地图的变化
            }
        });


        btn_navi.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if(mIsEngineInitSuccess){
                    navi();
                }
            }
        });

    }


    private void init() {
        // 获得地图控件引用
        mMapView = (MapView) findViewById(R.id.bmapView);
        // 获得地图控制器
        mBaiduMap = mMapView.getMap();// MapView与BaiduMap一一对应

        // 定位核心类
        mLocationClient = new LocationClient(getApplicationContext());
        // 定位回调接口
        myLocationListener = new MyLocationListener();
        // 定位按钮
        btn_location = (Button) findViewById(R.id.location);
        // 设置是否允许定位图层,只有先允许定位图层后设置定位数据才会生效
        mBaiduMap.setMyLocationEnabled(true);

        //poi搜索核心类
        mPoiSearch = PoiSearch.newInstance();
        //poi搜索回调接口
        mySearchResultListener = new MySearchResultListener();      
        // 搜索按钮
        btn_search = (Button) findViewById(R.id.search);

        //导航按钮
        btn_navi=(Button) findViewById(R.id.navi);
        //导航引擎初始化接口。调用该接口会触发SDK鉴权流程
        BaiduNaviManager.getInstance().initEngine(this, getSdcardDir()
                , mNaviEngineInitListener, null);
    }

    /**
     * 定位
     */
    private void location() {
        // 设置mLocationClient数据,如是否打开GPS,使用LocationClientOption类.
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式
        option.setCoorType("bd09ll");// 返回的定位结果是百度经纬度,默认值gcj02
        option.setScanSpan(3000);// 设置发起定位请求的间隔时间为5000ms
        option.setIsNeedAddress(true);// 返回的定位结果包含地址信息
        option.setNeedDeviceDirect(true);// 返回的定位结果包含手机机头的方向
        option.setOpenGps(true);// 打开GPS
        mLocationClient.setLocOption(option);
        mLocationClient.registerLocationListener(myLocationListener);
    }

    public class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            // mapView 销毁后不在处理新接收的位置
            if (location == null || mMapView == null)
                return;
            // 获取服务器回传的当前经纬度
            latitude=location.getLatitude();
            longitude=location.getLongitude();
            mCurrentLatLng = new LatLng(location.getLatitude(),
                    location.getLongitude());
            // 构造定位数据
            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())// 获取定位精度
                    .latitude(location.getLatitude())// 获取纬度坐标
                    .longitude(location.getLongitude())// 获取精度坐标
                    .build();
            mBaiduMap.setMyLocationData(locData);// 设置定位数据      

        }
    }


    /**
     * poi检索(圆形)
     */
    private void search() {
        mPoiSearch.setOnGetPoiSearchResultListener(mySearchResultListener);
        // PoiSearch需要设置相关参数,比如关键字,距离等
        PoiNearbySearchOption pnso = new PoiNearbySearchOption();
        pnso.keyword("美食");
        pnso.location(mCurrentLatLng);
        pnso.radius(1000);
        mPoiSearch.searchNearby(pnso);
    }   

    public class MySearchResultListener implements OnGetPoiSearchResultListener {

        @Override
        public void onGetPoiDetailResult(final PoiDetailResult poiDetailResult) {
            if (poiDetailResult.error != SearchResult.ERRORNO.NO_ERROR) {
                // 检索失败
            } else {
                // 点击marker showInfoWindow
                mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {
                    private BitmapDescriptor descriptor;

                    @Override
                    public boolean onMarkerClick(Marker arg0) {
                        // 设置弹窗 (View arg0, LatLng arg1, int arg2) y 偏移量 ,
                        Button btn = new Button(getApplicationContext());
                        btn.setBackgroundColor(0xAA00FF00);
                        btn.setText(poiDetailResult.getName());
                        // btn 变成 View 图片                       
                        descriptor = BitmapDescriptorFactory.fromView(btn);

                        InfoWindow mInfoWindow = new InfoWindow(descriptor,
                                poiDetailResult.getLocation(), -60,
                                new OnInfoWindowClickListener() {

                                    public void onInfoWindowClick() {
                                        // 点击infoWindow可以触发二次检索,跳转界面
                                        // 隐藏弹窗!
                                        mBaiduMap.hideInfoWindow();
                                    }
                                });
                        mBaiduMap.showInfoWindow(mInfoWindow);
                        return false;
                    }
                }); 

            }
        }

        @Override
        public void onGetPoiResult(PoiResult poiResult) {
            // 首先判断检索结果是否有错,在判断检索结果是否为空
            if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {
                if (poiResult != null) {
                    mBaiduMap.clear();
                    // 绑定Overlay
                    MyPoiOverlay poiOverlay = new MyPoiOverlay(mBaiduMap);
                    mBaiduMap.setOnMarkerClickListener(poiOverlay);
                    // 设置数据到overlay
                    poiOverlay.setData(poiResult);
                    poiOverlay.addToMap();
                    // 缩放地图,使所有Overlay都在合适的视野内 注: 该方法只对Marker类型的overlay有效
                    poiOverlay.zoomToSpan();
                }

            } else {
                Toast.makeText(getApplicationContext(), "无结果",
                        Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 自定义PoiOverlay
    class MyPoiOverlay extends PoiOverlay {

        public MyPoiOverlay(BaiduMap baiduMap) {
            super(baiduMap);
        }

        @Override
        public boolean onPoiClick(int index) {
            super.onPoiClick(index);
            PoiInfo poi = getPoiResult().getAllPoi().get(index);
            mPoiSearch.searchPoiDetail((new PoiDetailSearchOption())
                    .poiUid(poi.uid));
            return super.onPoiClick(index);
        }

    }
    /**
     * 导航
     */
    protected void navi() {
        //通过指定导航的起终点启动导航
        BaiduNaviManager.getInstance().launchNavigator(this
                , latitude
                , longitude
                , "demo公司"
                , 32.332000
                , 120.265000
                , new city"             
                , NE_RoutePlan_Mode.ROUTE_PLAN_MOD_MIN_TIME//算路方式
                , true
                , BaiduNaviManager.STRATEGY_FORCE_ONLINE_PRIORITY//强制离线优先
                , new OnStartNavigationListener(){
                    //启动导航的监听器,由开发者实现跳转到基于SDK自定义的[离线数据下载页]
                    @Override
                    public void onJumpToDownloader() {                      
                    }
                    //启动导航的监听器,由开发者实现跳转到基于SDK自定义的[导航页]
                    @Override
                    public void onJumpToNavigator(Bundle configParams) {
                        Intent intent=new Intent(MainActivity.this,BNavigatorActivity.class);
                        intent.putExtras(configParams);
                        startActivity(intent);                      
                    }           
        });

    }

    @Override
    protected void onStart() {
        location();
        mLocationClient.start();// 开启定位请求
        super.onStart();
    }

    @Override
    protected void onResume() {
        mMapView.onResume();
        super.onResume();
    }

    @Override
    protected void onPause() {
        mLocationClient.stop();// 停止定位
        mMapView.onPause();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        mMapView.onDestroy();
        super.onDestroy();
    }
}
import com.baidu.navisdk.BaiduNaviManager;
import com.baidu.navisdk.comapi.mapcontrol.BNMapController;
import com.baidu.navisdk.comapi.routeplan.BNRoutePlaner;
import com.baidu.navisdk.comapi.tts.BNTTSPlayer;
import com.baidu.navisdk.comapi.tts.BNavigatorTTSPlayer;
import com.baidu.navisdk.comapi.tts.IBNTTSPlayerListener;
import com.baidu.navisdk.model.datastruct.LocData;
import com.baidu.navisdk.model.datastruct.SensorData;
import com.baidu.navisdk.ui.routeguide.BNavigator;
import com.baidu.navisdk.ui.routeguide.IBNavigatorListener;
import com.baidu.navisdk.ui.widget.RoutePlanObserver;
import com.baidu.navisdk.ui.widget.RoutePlanObserver.IJumpToDownloadListener;
import com.baidu.nplatform.comapi.map.MapGLSurfaceView;

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.View;

public class BNavigatorActivity extends Activity {

    //导航视图监听器
    private IBNavigatorListener mBNavigatorListener=new IBNavigatorListener() {

        @Override
        public void onYawingRequestSuccess() {
            // TODO 偏航请求成功          
        }

        @Override
        public void onYawingRequestStart() {
            // TODO 开始偏航请求          
        }

        @Override
        public void onPageJump(int jumpTiming, Object arg1) {
            // TODO 页面跳转回调
            if(IBNavigatorListener.PAGE_JUMP_WHEN_GUIDE_END==jumpTiming){
                finish();
            }else if(IBNavigatorListener.PAGE_JUMP_WHEN_ROUTE_PLAN_FAIL==jumpTiming){
                finish();
            }           
        }

        @Override
        public void notifyViewModeChanged(int arg0) {

        }

        @Override
        public void notifyStartNav() {

        }

        @Override
        public void notifySensorData(SensorData arg0) {

        }

        @Override
        public void notifyNmeaData(String arg0) {

        }

        @Override
        public void notifyLoacteData(LocData arg0) {

        }

        @Override
        public void notifyGPSStatusData(int arg0) {

        }
    };

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //创建NMapView
        MapGLSurfaceView nMapView = BaiduNaviManager.getInstance().createNMapView(this);
        //设置支持卫星视图
        nMapView.setSatellite(true);
        //创建导航视图
        View navigatorView = BNavigator.getInstance().init(BNavigatorActivity.this, getIntent().getExtras(), nMapView);
        //填充视图
        setContentView(navigatorView);

        BNavigator.getInstance().setListener(mBNavigatorListener);
        //初始化就绪后发起导航,分为算路后导航(百度地图)与直接发起导航(百度导航) 两种模式 
        BNavigator.getInstance().startNav();

        //初始化TTS
        BNTTSPlayer.initPlayer();
        //设置TTS回调
        BNavigatorTTSPlayer.setTTSPlayerListener(new IBNTTSPlayerListener() {

            @Override
            public int playTTSText(String arg0, int arg1) {
                // TODO Auto-generated method stub
                return BNTTSPlayer.playTTSText(arg0, arg1);
            }

            @Override
            public void phoneHangUp() {
                // 手机挂断
            }

            @Override
            public void phoneCalling() {
                // 通话中
            }

            @Override
            public int getTTSState() {
                return BNTTSPlayer.getTTSState();
            }
        });



        BNRoutePlaner.getInstance().setObserver(new RoutePlanObserver(this,
                new IJumpToDownloadListener() {

                    @Override
                    public void onJumpToDownloadOfflineData() {

                    }
                }));

    };


    @Override  
    public void onResume() {  
        BNavigator.getInstance().resume();  
        super.onResume();  
        BNMapController.getInstance().onResume();  
    };  

    @Override  
    public void onPause() {  
        BNavigator.getInstance().pause();  
        super.onPause();  
        BNMapController.getInstance().onPause();  
    }  

    @Override  
    public void onConfigurationChanged(Configuration newConfig) {  
        BNavigator.getInstance().onConfigurationChanged(newConfig);  
        super.onConfigurationChanged(newConfig);  
    }  

    public void onBackPressed(){  
        BNavigator.getInstance().onBackPressed();  
    }  

    @Override  
    public void onDestroy(){  
        BNavigator.destory();  
        BNRoutePlaner.getInstance().setObserver(null);  
        super.onDestroy();  
    }

}

此demo已上传csdn,下载地址为:
http://download.csdn.net/detail/csdn1027719307/8700107

你可能感兴趣的:(百度地图开发)