因为年前的工作中用到了百度地图的定位 导航功能,然后又去翻阅了百度sdk相关的api后进行开发,现在对其进行一些整理,方便后面遇到相关开发时使用。
开发之前,先进行准备工作,在百度地图的开发者网站上下载相关的sdk,导入AS中的libs文件中,然后创建jniLibs的文件夹,将其相关的文件复制进去后,引用即可,然后申请百度地图相关的key秘钥,导入相关的权限,根据百度官方的流程进行即可。
首先先在xml文件中引入百度的图view
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.l.mapdemo.MainActivity">
<com.baidu.mapapi.map.MapView
android:id="@+id/mv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
</RelativeLayout>
其进行开发之前 必须先初始化sdk的个组件,如果是多次引用的话,也可以将其抽取成base类进行使用
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
将百度地图生命周期与activity的进行绑定
@Override
protected void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
protected void onStart() {
super.onStart();
mBaiduMap.setMyLocationEnabled(true);
if (!mLocationClient.isStarted()) {
mLocationClient.start();
}
}
@Override
protected void onStop() {
super.onStop();
mLocationClient.stop();
}
首先进行定位的开发
定位相关的公共类
//定位相关
private LocationClient mLocationClient = null;
private boolean isFristLocation = true;
根据百度sdk提供的官方文档可以看到 其定位相关的类如下
private void initLocation() {
mLocationClient = new LocationClient(getApplicationContext()); //声明LocationClient类
initLocationOps();
//注册监听函数
mLocationClient.registerLocationListener(new BDLocationListener() {
@Override
public void onReceiveLocation(BDLocation location) {
//mapview 销毁后不再处理新的接收位置
if (location == null || mMapView == null)
return;
//构造定位数据
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
//此处设置开发者获取到的方向信息
.latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
//设置定位数据
mBaiduMap.setMyLocationData(locData);
//第一次定位时,将地图位置移动到当前位置
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
mLastLocationData = ll;
if (isFristLocation) {
isFristLocation = false;
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
mBaiduMap.animateMapStatus(u);
}
}
});
}
private void initLocationOps() {
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
int span = 1000;
option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
option.setOpenGps(true);//可选,默认false,设置是否使用gps
option.setLocationNotify(true);//可选,默认false,设置是否当GPS有效时按照1S/1次频率输出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);
}
定位相关基本完成。
导航相关代码:在百度提供的官方demo中找到BNDemoGuideActivity类,这是导航相关的类,将其复制进自己的工程,改掉一些报红的类即可
然后在自己的MainnActivity中百度提供的Demo中的
private MapView mMapView;
private BaiduMap mBaiduMap;
private Button mBtmine;
private String mSDCardPath = null;
private static final String APP_FOLDER_NAME = "BNSDKSimpleDemo";
private final static String authBaseArr[] =
{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION};
private final static String authComArr[] = {Manifest.permission.READ_PHONE_STATE};
private final static int authBaseRequestCode = 1;
private final static int authComRequestCode = 2;
private boolean hasInitSuccess = false;
private boolean hasRequestComAuth = false;
public static final String ROUTE_PLAN_NODE = "routePlanNode";
public static List<Activity> activityList = new LinkedList<Activity>();
public static final String RESET_END_NODE = "resetEndNode";
//更新地图的设置
mBaiduMap = mMapView.getMap();
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(18.0f);
mBaiduMap.setMapStatus(msu);
if (initDirs()) {
initNavi();
}
private boolean initDirs() {
mSDCardPath = getSdcardDir();
if (mSDCardPath == null) {
return false;
}
File f = new File(mSDCardPath, APP_FOLDER_NAME);
if (!f.exists()) {
try {
f.mkdir();
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
return true;
}
String authinfo = null;
/**
* 内部TTS播报状态回传handler
*/
private Handler ttsHandler = new Handler() {
public void handleMessage(Message msg) {
int type = msg.what;
switch (type) {
case BaiduNaviManager.TTSPlayMsgType.PLAY_START_MSG: {
// showToastMsg("Handler : TTS play start");
break;
}
case BaiduNaviManager.TTSPlayMsgType.PLAY_END_MSG: {
// showToastMsg("Handler : TTS play end");
break;
}
default:
break;
}
}
};
/**
* 内部TTS播报状态回调接口
*/
private BaiduNaviManager.TTSPlayStateListener ttsPlayStateListener = new BaiduNaviManager.TTSPlayStateListener() {
@Override
public void playEnd() {
// showToastMsg("TTSPlayStateListener : TTS play end");
}
@Override
public void playStart() {
// showToastMsg("TTSPlayStateListener : TTS play start");
}
};
public void showToastMsg(final String msg) {
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
}
private boolean hasBasePhoneAuth() {
// TODO Auto-generated method stub
PackageManager pm = this.getPackageManager();
for (String auth : authBaseArr) {
if (pm.checkPermission(auth, this.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
private boolean hasCompletePhoneAuth() {
// TODO Auto-generated method stub
PackageManager pm = this.getPackageManager();
for (String auth : authComArr) {
if (pm.checkPermission(auth, this.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
private void initNavi() {
BNOuterTTSPlayerCallback ttsCallback = null;
// 申请权限
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (!hasBasePhoneAuth()) {
this.requestPermissions(authBaseArr, authBaseRequestCode);
return;
}
}
BaiduNaviManager.getInstance().init(this, mSDCardPath, APP_FOLDER_NAME, new BaiduNaviManager.NaviInitListener() {
@Override
public void onAuthResult(int status, String msg) {
if (0 == status) {
authinfo = "key校验成功!";
} else {
authinfo = "key校验失败, " + msg;
}
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, authinfo, Toast.LENGTH_LONG).show();
}
});
}
public void initSuccess() {
Toast.makeText(MainActivity.this, "百度导航引擎初始化成功", Toast.LENGTH_SHORT).show();
hasInitSuccess = true;
initSetting();
}
public void initStart() {
Toast.makeText(MainActivity.this, "百度导航引擎初始化开始", Toast.LENGTH_SHORT).show();
}
public void initFailed() {
Toast.makeText(MainActivity.this, "百度导航引擎初始化失败", Toast.LENGTH_SHORT).show();
}
}, null, ttsHandler, ttsPlayStateListener);
}
private void initSetting() {
// BNaviSettingManager.setDayNightMode(BNaviSettingManager.DayNightMode.DAY_NIGHT_MODE_DAY);
BNaviSettingManager
.setShowTotalRoadConditionBar(BNaviSettingManager.PreViewRoadCondition.ROAD_CONDITION_BAR_SHOW_ON);
BNaviSettingManager.setVoiceMode(BNaviSettingManager.VoiceMode.Veteran);
// BNaviSettingManager.setPowerSaveMode(BNaviSettingManager.PowerSaveMode.DISABLE_MODE);
BNaviSettingManager.setRealRoadCondition(BNaviSettingManager.RealRoadCondition.NAVI_ITS_ON);
}
private String getSdcardDir() {
if (Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
return Environment.getExternalStorageDirectory().toString();
}
return null;
}
private void addDestInfoOverlay(LatLng latLng) {
mBaiduMap.clear();
OverlayOptions options = new MarkerOptions().position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_geo))
.zIndex(5);
mBaiduMap.addOverlay(options);
}
设置目的地以及导航相关的方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 66) {
String result = data.getExtras().getString("result");//得到新Activity 关闭后返回的数据
jd = Double.parseDouble(result);
String result2 = data.getExtras().getString("result2");
wd = Double.parseDouble(result2);
LatLng latLng = new LatLng(wd, jd);
mDestLocationData = latLng;
addDestInfoOverlay(latLng);
Toast.makeText(MainActivity.this, "设置目的地成功", Toast.LENGTH_SHORT).show();
} else if (resultCode == 33) {
String result3 = data.getExtras().getString("result");
Toast.makeText(this, "点击取消", Toast.LENGTH_SHORT).show();
}
}
private void routeplanToNavi(boolean mock) {
BNRoutePlanNode.CoordinateType coType = BNRoutePlanNode.CoordinateType.GCJ02;
if (!hasInitSuccess) {
Toast.makeText(MainActivity.this, "还未初始化!", Toast.LENGTH_SHORT).show();
}
// 权限申请
if (android.os.Build.VERSION.SDK_INT >= 23) {
// 保证导航功能完备
if (!hasCompletePhoneAuth()) {
if (!hasRequestComAuth) {
hasRequestComAuth = true;
this.requestPermissions(authComArr, authComRequestCode);
return;
} else {
Toast.makeText(MainActivity.this, "没有完备的权限!", Toast.LENGTH_SHORT).show();
}
}
}
BNRoutePlanNode sNode = null;
BNRoutePlanNode eNode = null;
coType = BNRoutePlanNode.CoordinateType.BD09LL;
//mLastLocationData
//mDestLocationData
// sNode = new BNRoutePlanNode(116.30142, 40.05087, "百度大厦", null, coType);
// eNode = new BNRoutePlanNode(116.39750, 39.90882, "北京天安门", null, coType);
sNode = new BNRoutePlanNode(mLastLocationData.longitude, mLastLocationData.latitude, "我的位置", null, coType);
eNode = new BNRoutePlanNode(jd, wd, "目标地点", null, coType);
// Toast.makeText(this, "目标地点确定", Toast.LENGTH_SHORT).show();
eNode = new BNRoutePlanNode(mDestLocationData.longitude, mDestLocationData.latitude, "目的地位置", null, coType);
if (sNode != null && eNode != null) {
List<BNRoutePlanNode> list = new ArrayList<BNRoutePlanNode>();
list.add(sNode);
list.add(eNode);
BaiduNaviManager.getInstance().launchNavigator(this, list, 1, mock, new DemoRoutePlanListener(sNode));
}
}
public class DemoRoutePlanListener implements BaiduNaviManager.RoutePlanListener {
private BNRoutePlanNode mBNRoutePlanNode = null;
public DemoRoutePlanListener(BNRoutePlanNode node) {
mBNRoutePlanNode = node;
}
@Override
public void onJumpToNavigator() {
/*
* 设置途径点以及resetEndNode会回调该接口
*/
for (Activity ac : activityList) {
if (ac.getClass().getName().endsWith("BNDemoGuideActivity")) {
return;
}
}
Intent intent = new Intent(MainActivity.this, BNDemoGuideActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable(ROUTE_PLAN_NODE, (BNRoutePlanNode) mBNRoutePlanNode);
intent.putExtras(bundle);
startActivity(intent);
}
@Override
public void onRoutePlanFailed() {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "算路失败", Toast.LENGTH_SHORT).show();
}
}