慕课视频:Android-百度地图之导航
http://www.imooc.com/learn/670
Android 百度地图 SDK v3.0.0
转载链接【鸿神】:http://blog.csdn.net/lmj623565791/article/category/2392939
Android:百度地图 点聚合功能
http://m.blog.csdn.net/article/details?id=52386097
百度地图应用实例操作
http://m.blog.csdn.net/blog/index?username=rt77777
android 获取GPS经纬度在百度地图上绘制轨迹
http://m.blog.csdn.net/article/details?id=17842697
百度地图应用实例
http://www.jianshu.com/p/ade5f2a7f320
Android地图开发
http://blog.csdn.net/column/details/android-jacksen-map.html
百度地图开发之实现运动轨迹 <一>
http://blog.csdn.net/u013430507/article/details/44064761
百度地图开发之实现运动轨迹 <二>
http://blog.csdn.net/u013430507/article/details/44065409
Android 百度地图 SDK v3.0.0 (二) 定位与结合方向传感器
http://blog.csdn.net/u013430507/article/details/44065765
百度地图开发文档地址
http://lbsyun.baidu.com/index.php?title=androidsdk/guide/hellobaidumap
程序包api文档
http://wiki.lbsyun.baidu.com/cms/androidsdk/doc/v4_3_0/index.html
《一》生成SHA1时注意:
keytool的使用:目录下的keytool全路名
dubug版:keytool -list -v -keystore debug.keystore
注意:debug.keystore(默认没有口令)
上线版:keytool -list -v -keystore 123.jks
口令就是keystore的密码
《二》复制jar包
(1)直接复制BaiduMap_AndroidSDK_v4.2.1_Sample\BaiduMapsApiDemo\libs
目录下的jar包《除去v4》
(2) 生成并粘贴main/jniLibs下面的so文件(5个)
《三》配置功能清单文件
权限以及《meta-data》替换成自己应用生成的value值(key)
《四》布局layout中添加map组件
《五》添加图层
获取地图的实例
//添加交通图
mapView.setTrafficEnabled(true);
//mapView.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
/* //普通地图
mapView.setMapType(BaiduMap.MAP_TYPE_NORMAL);
//卫星地图
mapView.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
//空白地图, 基础地图瓦片将不会被渲染。在地图类型中设置为NONE,将不会使用流量下载基础地图瓦片图层。
// 使用场景:与瓦片图层一起使用,节省流量,提升自定义瓦片图下载速度。
mapView.setMapType(BaiduMap.MAP_TYPE_NONE);
//开启交通图 实时交通图
mapView.setTrafficEnabled(true);
//开启交通图 百度城市热力图
mapView.setBaiduHeatMapEnabled(true);
《六》添加覆盖物
//设置地图点击事件
mapView.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {//坐标
mapView.clear();//清除地图上的所有的覆盖物
//创建一个覆盖物的图标
BitmapDescriptor icon = BitmapDescriptorFactory
.fromResource(R.mipmap.ic_launcher);
//创建一个覆盖物
OverlayOptions options =
new MarkerOptions().position(latLng).icon(icon);
//将覆盖物添加到地图中
mapView.addOverlay(options);
}
@Override
public boolean onMapPoiClick(MapPoi mapPoi) {
return false;
}
});
《七》添加覆盖物的点击事件
mapView.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
Toast.makeText(MainActivity.this, "别点我讨厌!!", Toast.LENGTH_SHORT).show();
return false;
}
});
完整代码:
public class MainActivity extends AppCompatActivity {
private BaiduMap mapView;
private MapView map;
private PoiSearch poiSearch;
private ShareUrlSearch shareUrlSearch;
private RoutePlanSearch routePlanSearch;
private GeoCoder geoCoder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(getApplicationContext());
setContentView(R.layout.activity_main);
initView();
initListener();
}
private void initListener() {
//添加地图的事件
//initMapListener();
//添加marker点击事件
//initMarkerListener();
//检索监听
initPoiListener();
//设置分享监听
initShareListener();
//创建线路规划监听
initRoutePlanListener();
//地理编码
initGeoCoderListener();
}
private void initGeoCoderListener() {
geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
@Override
public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {
Log.i("TAG", "onGetGeoCodeResult: "+geoCodeResult.getLocation().toString());
}
@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
String address = reverseGeoCodeResult.getAddress();
Log.i("TAG", "onGetGeoCodeResult: ");
}
});
}
private void initRoutePlanListener() {
routePlanSearch.setOnGetRoutePlanResultListener(new OnGetRoutePlanResultListener() {
@Override
public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
//步行路线结果回调
if (walkingRouteResult == null ||
walkingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
return;
}
mapView.clear();
WalkingRouteOverlay overly = new MyWalk(mapView);
overly.setData(walkingRouteResult.getRouteLines().get(0));
overly.addToMap();
overly.zoomToSpan();
}
@Override
public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
//换乘路线结果回调
}
@Override
public void onGetMassTransitRouteResult(MassTransitRouteResult massTransitRouteResult) {
//跨城公共交通路线结果回调
}
@Override
public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
//驾车路线结果回调
//骑行路线回调
if (drivingRouteResult == null ||
drivingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
return;
}
mapView.clear();
DrivingRouteOverlay overlay = new MyDriver(mapView);
overlay.setData(drivingRouteResult.getRouteLines().get(0));
overlay.addToMap();
overlay.zoomToSpan();
}
@Override
public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {
//室内路线规划回调
}
@Override
public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {
//骑行路线结果回调
if (bikingRouteResult == null ||
bikingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
return;
}
mapView.clear();
BikingRouteOverlay overlay = new MyBinking(mapView);
overlay.setData(bikingRouteResult.getRouteLines().get(0));
overlay.addToMap();
overlay.zoomToSpan();
}
});
}
//创建步行路线覆盖物
class MyWalk extends WalkingRouteOverlay {
public MyWalk(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public boolean onPolylineClick(Polyline polyline) {
return super.onPolylineClick(polyline);
}
}
//创建架车路线覆盖物
class MyDriver extends DrivingRouteOverlay {
public MyDriver(BaiduMap baiduMap) {
super(baiduMap);
}
}
//创建步行路线覆盖物
class MyBinking extends BikingRouteOverlay {
public MyBinking(BaiduMap baiduMap) {
super(baiduMap);
}
}
//=======分享的第二个回调(shareUrl)==>url=====
private void initShareListener() {
shareUrlSearch.setOnGetShareUrlResultListener(
new OnGetShareUrlResultListener() {
@Override
public void onGetPoiDetailShareUrlResult(final ShareUrlResult shareUrlResult){
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,
""+shareUrlResult.getUrl(), Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onGetLocationShareUrlResult(ShareUrlResult shareUrlResult) {
}
@Override
public void onGetRouteShareUrlResult(ShareUrlResult shareUrlResult) {
}
});
}
//=============poi检索监听==============
private void initPoiListener() {
poiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {
//获取POI检索结果
@Override
public void onGetPoiResult(PoiResult poiResult) {
//判断是否有结果
if (poiResult == null || poiResult.error != SearchResult.ERRORNO.NO_ERROR) {
Log.v("TAG", "没有找到相关搜索");
return;
}
//获取检索结果集
List<PoiInfo> list = poiResult.getAllPoi();
for (PoiInfo info : list) {
Log.i("TAG", "onGetPoiResult: " + info.name);
//添加标注物
/* BitmapDescriptor bitmapDescriptor
= BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher);
OverlayOptions options = new MarkerOptions().position(info.location)
.icon(bitmapDescriptor);
mapView.addOverlay(options);*/
//添加系统提供的标注物
mapView.clear();
MyOverly myOverly = new MyOverly(mapView);
myOverly.setData(poiResult);
myOverly.addToMap();
myOverly.zoomToSpan(); //自动放大
mapView.setOnMarkerClickListener(myOverly);
}
}
//poi搜索的回调详情 点击的时候调用此方法
@Override
public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
//=======分享的第一个回调poi(PoiInfo)==》request(shareUrl)=====
shareUrlSearch.requestPoiDetailShareUrl(
new PoiDetailShareURLOption()
.poiUid(poiDetailResult.getUid()));
/*shareUrlSearch.requestLocationShareUrl(
new LocationShareURLOption()
.location(poiDetailResult.getLocation())
.name("aaa").snippet("bbb"));*/
}
@Override
public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
}
});
}
class MyOverly extends PoiOverlay {
/**
* 构造函数
*
* @param baiduMap 该 PoiOverlay 引用的 BaiduMap 对象
*/
public MyOverly(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public boolean onPoiClick(int i) {
List<PoiInfo> allPoi = getPoiResult().getAllPoi();
Toast.makeText(MainActivity.this,
"" + allPoi.get(i).name, Toast.LENGTH_SHORT).show();
//
poiSearch.searchPoiDetail(
new PoiDetailSearchOption().poiUid(allPoi.get(i).uid));
return super.onPoiClick(i);
}
}
private void initMarkerListener() {
mapView.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
Toast.makeText(MainActivity.this, "别点我讨厌!!", Toast.LENGTH_SHORT).show();
return false;
}
});
}
private void initMapListener() {
//设置地图点击事件
mapView.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {//坐标
mapView.clear();//清除地图上的所有的覆盖物
//创建一个覆盖物的图标
BitmapDescriptor icon = BitmapDescriptorFactory
.fromResource(R.mipmap.ic_launcher);
//创建一个覆盖物
OverlayOptions options =
new MarkerOptions().position(latLng).icon(icon);
//将覆盖物添加到地图中
mapView.addOverlay(options);
}
@Override
public boolean onMapPoiClick(MapPoi mapPoi) {
return false;
}
});
}
private void initView() {
map = (MapView) findViewById(R.id.mapview);
//获取当前的地图
mapView = map.getMap();
//初始化POI检索
poiSearch = PoiSearch.newInstance();
//初始化分享
shareUrlSearch = ShareUrlSearch.newInstance();
//创建线路规划的实例
routePlanSearch = RoutePlanSearch.newInstance();
//地理编码
//地理编码
geoCoder = GeoCoder.newInstance();
}
/*
*
* 添加图层
*
* */
public void btn1(View view) {
//添加交通图
mapView.setTrafficEnabled(true);
//mapView.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
/* //普通地图
mapView.setMapType(BaiduMap.MAP_TYPE_NORMAL);
//卫星地图
mapView.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
//空白地图, 基础地图瓦片将不会被渲染。在地图类型中设置为NONE,将不会使用流量下载基础地图瓦片图层。
// 使用场景:与瓦片图层一起使用,节省流量,提升自定义瓦片图下载速度。
mapView.setMapType(BaiduMap.MAP_TYPE_NONE);
//开启交通图 实时交通图
mapView.setTrafficEnabled(true);
//开启交通图 百度城市热力图
mapView.setBaiduHeatMapEnabled(true);*/
}
/*
* 添加覆盖物
*
* */
public void btn2(View view) {
//添加Marker
/* //经纬度
LatLng l = new LatLng(39.963175,116.400244);
//创建一个覆盖物的图标
BitmapDescriptor icon = BitmapDescriptorFactory
.fromResource(R.mipmap.ic_launcher);
//创建一个覆盖物
OverlayOptions options = new MarkerOptions().position(l).icon(icon);
//将覆盖物添加到地图中
mapView.addOverlay(options);*/
//添加几何图形
//添加一个几何图形
LatLng l1 = new LatLng(39.93925, 116.357428);
LatLng l2 = new LatLng(39.90925, 116.327428);
LatLng l3 = new LatLng(39.88925, 116.347428);
//将三个坐标添加到集合中
List<LatLng> pt = new ArrayList<>();
pt.add(l1);
pt.add(l2);
pt.add(l3);
OverlayOptions options = new PolygonOptions().points(pt)
//2 边宽 和边的颜色 , fillColor(填充的颜色)
.stroke(new Stroke(2, 0xAA00FF00)).fillColor(0xAA00FF00);
mapView.addOverlay(options);
}
/*
* POI检索
*
* */
public void btn3(View view) {
//城市内检索
/*
PoiCitySearchOption city(java.lang.String city)
检索城市
PoiCitySearchOption keyword(java.lang.String key)
搜索关键字
PoiCitySearchOption pageCapacity(int pageCapacity)
设置每页容量,默认为每页10条
PoiCitySearchOption pageNum(int pageNum)
分页编号
*/
/*poiSearch.searchInCity(
new PoiCitySearchOption().city("北京")
.keyword("ATM").pageNum(1).pageCapacity(10));*/
/**
keyword(java.lang.String key)
检索关键字
PoiNearbySearchOption location(LatLng location)
检索位置
PoiNearbySearchOption pageCapacity(int pageCapacity)
设置每页容量,默认为每页10条
PoiNearbySearchOption pageNum(int pageNum)
分页编号
PoiNearbySearchOption radius(int radius)
设置检索的半径范围
PoiNearbySearchOption sortType(PoiSortType sortType)
搜索结果排序规则,可选,默认
*/
//周边检索,有一个中心点
LatLng l1 = new LatLng(39.93925, 116.357428);
poiSearch.searchNearby(new PoiNearbySearchOption()
.radius(10000).pageCapacity(10).pageNum(1).location(l1).keyword("美食"));
}
/*
* 路线规划
* */
public void btn4(View view){
//路线 第一个参数是cityCode
第二个是具体地址
PlanNode stNode = PlanNode.withCityCodeAndPlaceName(132, "xxxx");
PlanNode endNode = PlanNode.withCityCodeAndPlaceName(132, "xxxx");
// routePlanSearch.transitSearch(new TransitRoutePlanOption()
// .city("北京").from(stNode).to(endNode));
routePlanSearch.drivingSearch(new DrivingRoutePlanOption()
.from(stNode).to(endNode));
// routePlanSearch.bikingSearch(new BikingRoutePlanOption().from(stNode).to(endNode));
}
/*
* 地理编码
* */
public void btn5(View view){
//将经纬度转找成地址
geoCoder.reverseGeoCode(new ReverseGeoCodeOption()
.location(new LatLng(39.946758,116.423134)));
//将地址转换成经纬度
// geoCoder.geocode(new GeoCodeOption()
// .address("北京").city("北京"));
}
public void btn6(View view){
onCreate();
}
public void btn7(View view){
//开启定位图层
mapView.setMyLocationEnabled(true);
}
public LocationClient mLocationClient = null;
public BDLocationListener myListener = new MyLocationListener();
public void onCreate() {
mLocationClient = new LocationClient(getApplicationContext());
//声明LocationClient类
mLocationClient.registerLocationListener( myListener );
//注册监听函数
initLocation();
mLocationClient.start(); //开启定位
}
/*
* 设置locationClient的参数
*
* */
private void initLocation(){
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);
}
/*
* 获取定位的信息
* */
private boolean isFirst = true;
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//获取定位结果
/* StringBuffer sb = new StringBuffer(256);
sb.append("time : ");
sb.append(location.getTime()); //获取定位时间
sb.append(location.getAddrStr());
String s = sb.toString();
Log.i("BaiduLocationApiDem", sb.toString());*/
// 构造定位数据
MyLocationData locData = new MyLocationData.Builder()
//设置精确度
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100)
//设置纬度
.latitude(location.getLatitude())
//设置经度
.longitude(location.getLongitude())
.build();
// 设置定位数据
mapView.setMyLocationData(locData);
if (isFirst){
isFirst = false; //只会在第一次更新的时候才更新
LatLng lat = new LatLng(location.getLatitude(),
location.getLongitude());
//第一个参数是坐标,第二个参数是缩放值
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLngZoom(lat,13);
mapView.animateMapStatus(mapStatusUpdate);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
map.onDestroy();
poiSearch.destroy();
}
@Override
protected void onPause() {
super.onPause();
map.onPause();
}
@Override
protected void onResume() {
super.onStop();
map.onResume();
}
}
开发中坑:
《坑一》安全码校验 MCodeCheck.apk,解决地图不出现的原因
安全码校验是真实运行的SAH1,需要把创建应用的SAH1覆盖,地图就会显示
注册配置的SHA1和运行的应用的SAH1必须保持一致,地图才会出现
《坑二》参考:http://blog.csdn.net/taoolee/article/details/49361569
java.lang.IllegalArgumentException: No config chosen
异常的原因是SDK找不到支持OPENGL的硬件.从论坛得知,用户钩选了Use Host Gup 选项,此选项是说模拟器使用用户物理机上的GPU。如果用户物理机没有独立显卡,就会报错,此种情况下不钩这个选项就可以了。模拟器设置问题,与sdk没关系.
直白点就是模拟器不行: 需要真机测试
《坑三》6.0 动态申请定位权限