- 分享SDK:sharesdk
- 后端SDK:Bmob
- 推送SDK:极光推送
- 短信SDK:验证码实现
一.百度API
百度地图API:
http://developer.baidu.com/map/
二.搭建地图环境
1.申请百度地图的key2.下载对应功能的sdk3.新建一个工程导入sdk到lib里面
1.申请KEY
**我们打开百度API官网-开发-Android SDK**
然后选择获取密钥
创建应用
我们在IDE里创建一个工程–BaiDuMapDemo
然后依次填入所需要的信息
这里很多人对这个SHA1值很疑问,那我先科普一下这个是什么玩意吧
什么是SHA1?
安全哈希
算法
(Secure Hash Algorithm)主要适用于数字签名标准 (Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。 SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要。
那我们该如何去获取呢?
Eclipse获取方法
Android Studio获取方法
借鉴博文:
http://blog.csdn.net/kezhongke/article/details/42678077
好了,这里注意一下,这里我用com.lgl.baidumapdemo这个包名官方提示我敏感词,所以我换了一个,本质上是没有任何影响的,不用纠结,当我们提交之后,就可以获取到key了
2.下载SDK
我想我不用多说什么的,这里需要自定义下载,也就是说你需要什么功能你就选择什么功能,这里做demo的话全部下载了,这里也不提供下载了,你们可以自己去下载,我把地址给出来吧:
SDK下载地址:
http://developer.baidu.com/map/index.php?title=androidsdk/sdkandev-download
3.配置工程
首先我们把下载的sdk全部放在lib库里面,有点多,毕竟百度地图的功能还是可以的,不过会显得很臃肿,建议需要什么功能就放哪个架包吧,下载的时候我相关的demo和文档说明的
Eclipse
1. 在Eclipse 中选中工程,右键选 Properties->Java Build Path->Order and Export 使 Android Private Libraries处于勾选状态; 2. Project -> clean-> clean all
Android Studio
第一步:在工程app/libs目录下放入baidumapapi_vX_X_X.jar包,在src/main/目录下新建jniLibs目录,放入libBaiduMapSDK_vX_X_X_X.so如下图所示,注意jar和so的前3位版本号必须一致,并且保证使用一次下载的文件夹中的两个文件,不能不同功能组件的jar或so交叉使用。 第二步:导入jar包。菜单栏选择File->Project Structor->Modules->Dependencies,点击+号,选择File dependency,选择jar包导入。通过以上两步操作后,您就可以正常使用百度地图SDK为您提供的全部功能了。
三,HelloMap
1.权限
权限是必备的,而且说明文档里也十分详细的说明了
<
uses-permission
android:name
=
"android.permission.ACCESS_NETWORK_STATE"
/>
<
uses-permission
android:name
=
"android.permission.INTERNET"
/>
<
uses-permission
android:name
=
"com.android.launcher.permission.READ_SETTINGS"
/>
<
uses-permission
android:name
=
"android.permission.WAKE_LOCK"
/>
<
uses-permission
android:name
=
"android.permission.CHANGE_WIFI_STATE"
/>
<
uses-permission
android:name
=
"android.permission.ACCESS_WIFI_STATE"
/>
<
uses-permission
android:name
=
"android.permission.GET_TASKS"
/>
<
uses-permission
android:name
=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<
uses-permission
android:name
=
"android.permission.WRITE_SETTINGS"
/>
2.配置KEY
在application中添加开发密钥
data
android:name=
"com.baidu.lbsapi.API_KEY"
android:value=
"开发者 key"
/>
3.布局
在布局中直接添加
<
com
.baidu.mapapi.map.MapView
android:id=
"@+id/bmapView"
android:layout_width=
"fill_parent"
android:layout_height=
"fill_parent"
android:clickable=
"true"
/>
4.初始化
在应用程序创建时初始化 SDK引用的Context 全局变量:记住,一定要再setContentView之前执行并且初始化mapview
public
class
MainActivity
extends
Activity
{
private
MapView mMapView;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(getApplicationContext()); mMapView = (MapView) findViewById(R.id.bmapView); } }
5.地图的生命周期
前期工作我们都准备完成了,现在我们就把百度地图的生命周期给添加上
@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(); }
好了,准备了这么久,现在我们可以见证奇迹的时刻了
截图
好的,我们的初级教程到这里了,下面,就是一些高级的玩法了
四.地图进阶——基本控制
1.核心类
//三大核心类
1.
BMapManager
//百度地图管理工具
2.
MapView
//地图控件
——MapView的MKMapViewListener
//控件的点击事件
3.
MapController
//地图控制,必须MapViewy已经存在
//控制地图平移,缩放,选择等..
2.授权验证
我们做这种类型的应用,一般也就两个交互,一个就是key的授权,还有一个就是网络的授权了,我们我们在开始实现地图功能之前应该先去判断一下这两个条件是否实现了
实现广播机制
其实就是写个小广播,不需要很多代码
//初始化一个广播
private
MyBroadcastReceiver receiver;
class
MyBroadcastReceiver
extends
BroadcastReceiver
{
//实现一个广播
@Override
public
void
onReceive(Context context, Intent intent) { String action = intent.getAction();
// 网络错误
if
(action.equals(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR)) { Toast.makeText(MainActivity.
this
,
"无法连接网络"
, Toast.LENGTH_SHORT).show();
// key效验失败
}
else
if
(action.equals(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR)) { Toast.makeText(MainActivity.
this
,
"百度地图key效验失败"
,Toast.LENGTH_SHORT).show(); } } }
//在onCreate()方法中注册广播
receiver = new MyBroadcastReceiver(); IntentFilter
filter
= new IntentFilter();
// 网络错误
filter
.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);
// 效验key失败
filter
.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR); registerReceiver(receiver,
filter
);
//注意要在onDestroy()方法中销毁这个广播
unregisterReceiver(receiver);
广播写好了,我们来说一下这两条广播吧
逻辑就是当进入应用的时候sdk会去验证这两个条件,如果发现网络错误或者验证Key失败就会发送一条广播,广播接收者接收到了这条广播之后弹出一个Toast,当然,你如果想人性化一点也可以弹一个Dialog,这里作为demo就不做这么复杂的东西了
//网络错误
SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR
//key效验失败
SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR
3.设置地图缩放级别
虽然地图上是有按钮可以进行缩放的,但是再某些场景还是需要我们人工缩放,但是再缩放之前,我们应该先来了解一下缩放级别缩放级别在2.X是个分水岭,在2.X之前的级别是(3-18),之后是(3-19),主要是有两个区别1.修改了文件格式,具体是啥也不需要懂,只要知道,比如深圳的地图100M,2.x之后只要15M左右就行了2.增加了3D效果,这要在18或者19的级别上才可以看到我们先把BaiduMap给实现了
private
BaiduMap mBaiduMap;
//在onCreate()中mBaiduMap =
mMapView.getMap();
然后我们写一个方法让onCreate()调用
private
void
init(){
//描述地图将要发生的变化,使用工厂类MapStatusUpdateFactory创建,设置级别
//为18,进去就是18了,默认是12
MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.zoomTo(
18
); mBaiduMap.setMapStatus(mapStatusUpdate);
//是否显示缩放按钮
//mMapView.showZoomControls(false);
}
4.设置中心点(定位的初级实现)
你有没有发现,我们一进去地图显示的是北京天安门,其实这个就叫中心点,我们可以更改这个中心点同样的,我们写一个方法在onCreate()中调用
private
void
init(){
//经纬度(纬度,经度) 我们这里设置深圳世界之窗的位置
LatLng latlng =
new
LatLng(
22.5422870000
,
113.9804440000
); MapStatusUpdate mapStatusUpdate_circle = MapStatusUpdateFactory.newLatLng(latlng); mBaiduMap.setMapStatus(mapStatusUpdate_circle); }
截图
现在一进去中心点就会在世界之窗的坐标点了,我们定位的实现不就是获取到坐标点然后显示嘛!嘿嘿!
5.地图控制器(旋转,移动,缩放)
模拟点击 模拟器上运行按12345键实现,当然,你写Button的点击事件也可以
@Override
public
boolean
onKeyDown(
int
keyCode, KeyEvent event) {
switch
(keyCode) {
case
KeyEvent.KEYCODE_1:
//放大缩放级别,每次放大一个级别
MapStatusUpdate bigStatus = MapStatusUpdateFactory.zoomIn(); mBaiduMap.setMapStatus(bigStatus);
break
;
case
KeyEvent.KEYCODE_2:
//缩小缩放级别,每次缩小一个级别
MapStatusUpdate smallStatus = MapStatusUpdateFactory.zoomOut(); mBaiduMap.setMapStatus(smallStatus);
break
;
case
KeyEvent.KEYCODE_3:
//以屏幕中心点旋转
MapStatus mapStatus = mBaiduMap.getMapStatus();
//获取当前地图的状态
float
rotate = mapStatus.rotate;
//获取旋转角度
Log.i(
"旋转角度"
,
"rotate"
+rotate);
//用获取到的当前角度+30就是每次都旋转30° 范围0-360°
MapStatus rotates =
new
MapStatus.Builder().rotate(rotate+
30
).build();
//更新地图的选择
MapStatusUpdate rotateStatus = MapStatusUpdateFactory.newMapStatus(rotates); mBaiduMap.setMapStatus(rotateStatus);
break
;
case
KeyEvent.KEYCODE_4:
//以立体方式旋转
MapStatus mapStatusOver = mBaiduMap.getMapStatus();
//获取当前地图的状态
float
overlook = mapStatusOver.overlook;
//获取旋转角度
Log.i(
"旋转角度"
,
"overlook"
+overlook);
//弧角范围:0-45°
MapStatus overlooks =
new
MapStatus.Builder().overlook(overlook-
5
).build(); MapStatusUpdate overlookStatus = MapStatusUpdateFactory.newMapStatus(overlooks); mBaiduMap.setMapStatus(overlookStatus);
break
;
case
KeyEvent.KEYCODE_5:
//移动
MapStatusUpdate moveStatus = MapStatusUpdateFactory.newLatLng(
new
LatLng(
22.5422870000
,
113.9804440000
));
//带动画更新状态 默认300ms
mBaiduMap.animateMapStatus(moveStatus);
break
; }
6.指南针
//显示指南针
mBaiduMap.getUiSettings().setCompassEnabled(
true
);
//显示位置
mBaiduMap.getUiSettings().setCompassPosition(
new
Point(x, y));
7.地图事件
不是很常用,地图本身都是自带点击事件的
//设置地图单击监听
mBaiduMap.setOnMapClickListener(
new
OnMapClickListener() {
@Override
public
boolean
onMapPoiClick(MapPoi arg0) {
// TODO Auto-generated method stub
return
false
; }
@Override
public
void
onMapClick(LatLng arg0) {
// TODO Auto-generated method stub
} });
//覆盖物点击事件
mBaiduMap.setOnMarkerClickListener(
new
OnMarkerClickListener() {
@Override
public
boolean
onMarkerClick(Marker arg0) {
// TODO Auto-generated method stub
return
false
; } });
//设置地图双击监听
mBaiduMap.setOnMapDoubleClickListener(
new
OnMapDoubleClickListener() {
@Override
public
void
onMapDoubleClick(LatLng arg0) {
// TODO Auto-generated method stub
} });
//发起截图请求
mBaiduMap.snapshot(
new
SnapshotReadyCallback() {
@Override
public
void
onSnapshotReady(Bitmap arg0) {
// TODO Auto-generated method stub
} });
五.地图高阶——图层
1.什么是图层
一个地图是由很多个图层包裹的,还有级别,这是由图块决定的,你所看到的房子,学校什么的都是由图层实现的
2.图层分类
底图
基本的一个地图包括了各种建筑啥啥啥的
实时交通图
交通路况啥啥啥的
卫星图
就是从卫星上拍下来的嘛,哈哈哈哈,这些都一笔带过吧
其他
还有各种各样的,比如热力图啥的
3.覆盖物
覆盖物的层级压盖关系,如下(从上往下)
1
、基础底图(包括底图、底图道路、卫星图等);
2
、地形图图层(GroundOverlay);
3
、热力图图层(HeatMap);
4
、实时路况图图层(BaiduMap.setTrafficEnabled(
true
););
5
、百度城市热力图(BaiduMap.setBaiduHeatMapEnabled(
true
););
6
、底图标注(指的是底图上面自带的那些POI元素);
7
、几何图形图层(点、折线、弧线、圆、多边形);
8
、标注图层(Marker),文字绘制图层(
Text
);
9
、指南针图层(当地图发生旋转和视角变化时,默认出现在左上角的指南针);
10
、定位图层(BaiduMap.setMyLocationEnabled(
true
););
11
、弹出窗图层(InfoWindow);
12
、自定义View(MapView.addView(View););
4.基础图层切换
我们还是模拟操作,你也可以用Button点击事件去实现,这里就直接在onKeyDown()里面迷你按123键进行操作
//点击屏幕切换图层 从地图-卫星图-交通图
@Override
public
boolean
onKeyDown(
int
keyCode, KeyEvent event) {
switch
(keyCode) {
// 底图
case
KeyEvent.KEYCODE_1:
// 设置地图类型
mBaiduMap.setMapType(mBaiduMap.MAP_TYPE_NORMAL);
break
;
// 卫星图
case
KeyEvent.KEYCODE_2: mBaiduMap.setMapType(mBaiduMap.MAP_TYPE_SATELLITE);
break
;
// 交通图
case
KeyEvent.KEYCODE_3:
// 交通图是否打开
mBaiduMap.setTrafficEnabled(
true
);
break
; }
return
super
.onKeyDown(keyCode, event); }
5.免费申请标注
有时候我们会发现,你身处的环境附近有一些小店铺是没有在地图上标记的,也有一些小店铺就被百度地图给标记了,这是为什么了?这其实是百度的一个特有的功能,也不是技术活,纯粹就是跟申请账号一样
首先我们打开百度地图的官网:
http://map.baidu.com/
在最下方有个不起眼的文字,商户免费标注,点进去
按照这个步骤免费申请就得了,这里就不过多赘述
六.地图高阶——绘制覆盖物
所有叠加或覆盖到地图的内容,我们统称为地图覆盖物。如标注、矢量图形元素(包括:折线和多边形和圆)、定位图标等。覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的处理。覆盖物包括:本地覆盖物和搜索覆盖物本地覆盖物的抽象基类:OverlayOptions(核心类)圆形覆盖物: CircleOptions文字覆盖物: TextOptions
marker
覆盖物: MarkerOptions圆点覆盖物:DotOptionsground 覆盖物:GroundOverlayOptions圆点覆盖物:DotOptions多边形覆盖物:PolygonOptions折线覆盖物:PolylineOptions弧线覆盖物:ArcOptions
1.绘制圆
既然熟悉了这些基础的知识,那我们就先来绘制一个圆吧
写一个drawCircle()方法让onCreate()调用
// 绘制圆
private
void
drawCircle() {
// 1.创建自己
CircleOptions circleOptions =
new
CircleOptions();
// 2.设置数据 以世界之窗为圆心,1000米为半径绘制
circleOptions.center(
new
LatLng(
22.5422870000
,
113.9804440000
))
//中心
.radius(
1000
)
//半径
.fillColor(
0x60FF0000
)
//填充圆的颜色
.stroke(
new
Stroke(
10
,
0x600FF000
));
//边框的宽度和颜色
//把绘制的圆添加到百度地图上去
mBaiduMap.addOverlay(circleOptions); }
说了这么多,还是没有看图来的实在,我们来看下截图
2.绘制文字
同样的我们在写一个方法drawText();
// 绘制文字
private
void
drawText() { TextOptions textOptions =
new
TextOptions(); textOptions.fontColor(Color.RED)
//设置字体颜色
.text(
"自定义文字覆盖物"
)
//设置显示文本
.position(
new
LatLng(
22.5422870000
,
113.9804440000
))
//设置显示坐标
.fontSize(
20
)
//设置文本大小
.typeface(Typeface.SERIF)
//设置字体 Android的字体就三种,对称的,不对称的,等宽的
.rotate(
30
);
//设置旋转角度
//把绘制的圆添加到百度地图上去
mBaiduMap.addOverlay(textOptions); }
截图
3.绘制Mark覆盖物
Mark覆盖物就有趣多了,她是可以让我们自定义一张图片放上去的,就像那些打车软件一样可以让地图上看到一些车辆的信息同样的,不管三七二十一,我们继续写一个方法drawMark();先看看我这张要塞进去的图片
// 绘制mark覆盖物
private
void
drawMark() { MarkerOptions markerOptions =
new
MarkerOptions(); BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.logo);
// 描述图片
markerOptions.position(
new
LatLng(
22.5422870000
,
113.9804440000
))
// 设置位置
.icon(bitmap)
// 加载图片
.draggable(
true
)
// 支持拖拽
.title(
"世界之窗旁边的草房"
);
// 显示文本
//把绘制的圆添加到百度地图上去
mBaiduMap.addOverlay(markerOptions); }
截图
设置Mark覆盖物点击出现泡泡效果
不多说啥,先上个图给大家看看效果
实现这样的一个效果,其实就是加了一个pop
我们首先得自己定义一个activity_pop.xml
<
LinearLayout
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:orientation
=
"horizontal"
android:paddingBottom
=
"0dip"
>
<
LinearLayout
android:id
=
"@+id/user_info"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_marginBottom
=
"20dip"
android:layout_weight
=
"1"
android:background
=
"@drawable/popupmap"
android:gravity
=
"center_vertical"
android:orientation
=
"horizontal"
>
<
ImageView
android:id
=
"@+id/round"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_marginBottom
=
"2dip"
android:src
=
"@drawable/round"
/>
<
TextView
android:id
=
"@+id/title"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:ellipsize
=
"end"
android:text
=
"标题"
android:textSize
=
"20sp"
/>
<
ImageView
android:id
=
"@+id/roads"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:src
=
"@drawable/roads"
/>
LinearLayout
>
LinearLayout
>
预览是这样子的
首先,我们得初始化一些变量
//要显示的pop
private
View pop;
//pop中的文本信息
private
TextView title;
pop的初始化
//初始化
pop
private void initPop() {
pop
= View
.inflate
(getApplicationContext(), R
.layout.activity
_pop, null)
;
//必须使用百度的params LayoutParams params = new MapViewLayoutParams
.Builder
()
.layoutMode
(MapViewLayoutParams
.ELayoutMode.mapMode
) //按照经纬度设置
.position
(new LatLng(
22.5422870000
,
113.9804440000
)) //这个坐标无所谓的,但是不能传null
.width
(MapViewLayoutParams
.WRAP
_CONTENT) //宽度
.height
(MapViewLayoutParams
.WRAP
_CONTENT) //高度
.build
()
;
mMapView
.addView
(
pop
,params)
;
//先设置隐藏,点击的时候显示
pop
.setVisibility
(View
.INVISIBLE
)
;
//初始化这个title title = (TextView)
pop
.findViewById
(R
.id.title
)
;
}
mark的点击事件
/**mark的点击事件* 点击某一个mark在他上放显示泡泡 * 加载pop 添加到mapview 把他设置为隐藏 当点击的时候更新pop的位置 设置为显示 */
mBaiduMap.setOnMarkerClickListener(
new
OnMarkerClickListener() {
@Override
public
boolean
onMarkerClick(Marker result) {
//处理点击 ,当点击的时候更新并且显示位置
LayoutParams params =
new
MapViewLayoutParams.Builder(). layoutMode(MapViewLayoutParams.ELayoutMode.mapMode)
//按照经纬度设置位置
.position(result.getPosition())
//这个坐标无所谓的,但是不能传null
.width(MapViewLayoutParams.WRAP_CONTENT)
//宽度
.height(MapViewLayoutParams.WRAP_CONTENT)
//高度
.yOffset(-
5
)
//相距 正值往下 负值往上
.build(); mMapView.updateViewLayout(pop, params); pop.setVisibility(View.VISIBLE);
//更新下title
title.setText(result.getTitle());
return
true
; } });
这边新加一个功能,就是泡泡轮播切换,咱先看效果图:
其实实现这个不难,就是在设置icon的时候设置一个icons穿进去一个Bitmap的list
//拿上面那个方法直接改的设置icon
// 绘制mark覆盖物
private
void
drawMark() { MarkerOptions markerOptions =
new
MarkerOptions(); BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.logo);
// 描述图片
ArrayList bitmaps =
new
ArrayList(); bitmaps.add(bitmap);
//显示多个图片的来回切换,类似于帧动画
bitmaps.add(BitmapDescriptorFactory.fromResource(R.drawable.icon_geo)); markerOptions.position(
new
LatLng(
22.5422870000
,
113.9804440000
))
// 设置位置
//.icon(bitmap) // 加载图片
//切换图片
.icons(bitmaps) .period(
10
)
//切换时间
.draggable(
true
)
// 支持拖拽
.title(
"世界之窗旁边的草房"
);
// 显示文本
mBaiduMap.addOverlay(markerOptions); }
好的,Mark覆盖物写得差不多了 ,继续往下看吧
七.地图高阶——搜索路线标记
真不好意思,最近一直在加班,空闲的时间越来越少,没事,记录撸代码!!!接下来讲的是路线标记,相信不少人应该知道,地图导航的时候会帮你标记一条路线,我们今天就来实现这个功能,后续有哪些方法有疏漏,也希望博友能指点出来,毕竟我也是技术渣渣
百度地图移动版API集成搜索服务包括:位置检索、周边检索、范围检索、公交检索、驾乘检索、步行检索核心类: PoiSearch和OnGetPoiSearchResultListener RoutePlanSearch和OnGetRoutePlanResultListener实现思路初始化PoiSearch类,通过
set
OnGetPoiSearchResultListener方法注册搜索结果的监听对象OnGetPoiSearchResultListener ,实现异步搜索服务。通过自定义MySearchListener实现类,处理不同的回调方法,获得搜索结果。注意, OnGetPoiSearchResultListener只支持一个,以最后一次设置为准结合覆盖物展示搜索本地搜索覆盖物:PoiOverlay驾车路线覆盖物:DrivingRouteOverlay步行路线覆盖物:WalkingRouteOverlay换乘路线覆盖物:TransitOverlay
1.范围搜索,PoiOverlay的点击事件(矩形)
我们直接写一个search()方法让onCreate()调用吧直接撸代码,实现search();
// 范围搜索
private
void
search() {
// 实例化搜索方法
PoiSearch newInstance = PoiSearch.newInstance(); newInstance.setOnGetPoiSearchResultListener(
new
SearchListener());
// 发出搜索的请求 范围检索
PoiBoundSearchOption boundOption =
new
PoiBoundSearchOption(); LatLngBounds latLngBounds =
new
LatLngBounds.Builder()
// 确定两点坐标(东北,西南)
// 这里我们随机弄两个坐标 分别是深圳世界之窗附近
.include(
new
LatLng(
22.5441560000
,
113.9828800000
))
// 世界之窗右上角的美加广场
.include(
new
LatLng(
22.5413850000
,
113.9777770000
))
// 世界之窗左下角的一个不知道叫啥的街道
.build(); boundOption.bound(latLngBounds);
// 设置搜索的范围
boundOption.keyword(
"世界之窗"
);
// 搜索的关键字
newInstance.searchInBound(boundOption); }
实现它的Listener
class
SearchListener
implements
OnGetPoiSearchResultListener
{ @Override
public
void
onGetPoiDetailResult(PoiDetailResult result) { } @Override
public
void
onGetPoiResult(PoiResult result) {
// 收到发送过来的搜索请求之后我们进行处理
if
(result ==
null
|| SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error){ Toast.makeText(getApplicationContext(),
"未搜索到结果"
, Toast.LENGTH_LONG).show();
return
; }
//搜索类型的类
PoiOverlay overlay = PoiOverlay(mBaiduMap);
//处理搜索Poi的覆盖物
mBaiduMap.setOnMarkerClickListener(overlay);
// 把事件分发给overlay,overlay才能处理点击事件
overlay.setData(result);
//设置结果
overlay.addToMap;
//把搜索的结果添加到地图中去
overlay.zoomToSpan();
//自动缩放到所以的mark覆盖物都能看到
} }
自己实现它的点击事件
//自己实现点击事件
class
MyPoiOverlay
extends
PoiOverlay
{
public
MyPoiOverlay(BaiduMap arg0) {
super
(arg0); } @Override
public
boolean
onPoiClick(
int
index
) { PoiResult poiResult = getPoiResult(); PoiInfo poiInfo = poiResult.getAllPoi().get(
index
);
// 得到点击的那个poi信息
String text = poiInfo.name +
","
+ poiInfo.address; Toast.makeText(getApplicationContext(), text,
0
).show();
return
super
.onPoiClick(
index
); } }
官方的效果,点击后Toast
2.周边搜索(圆形)
周边搜索和范围搜索基本一致,我就直接上代码了
private
void
search() { poiSearch = PoiSearch.newInstance(); poiSearch.setOnGetPoiSearchResultListener(
new
MyListener()); PoiNearbySearchOption nearbyOption =
new
PoiNearbySearchOption(); nearbyOption.location(hmPos);
// 设置中心点
nearbyOption.radius(
1000
);
// 设置半径 单位是米
nearbyOption.keyword(
"加油站"
);
// 关键字
poiSearch.searchNearby(nearbyOption); }
class
MyListener
implements
OnGetPoiSearchResultListener
{ @Override
public
void
onGetPoiDetailResult(PoiDetailResult result) {
if
(result==
null
||SearchResult.ERRORNO.RESULT_NOT_FOUND==result.error){ Toast.makeText(getApplicationContext(),
"未搜索到结果"
,
0
).show();
return
; } String text = result.getAddress()+
"::"
+ result.getCommentNum() + result.getEnvironmentRating(); Toast.makeText(getApplicationContext(), text,
0
).show(); } @Override
public
void
onGetPoiResult(PoiResult result) {
if
(result==
null
||SearchResult.ERRORNO.RESULT_NOT_FOUND==result.error){ Toast.makeText(getApplicationContext(),
"未搜索到结果"
,
0
).show();
return
; } PoiOverlay overlay =
new
MyPoiOverlay(baiduMap);
// 搜索poi的覆盖物
baiduMap.setOnMarkerClickListener(overlay);
// 把事件分发给overlay,overlay才能处理点击事件
overlay.setData(result);
// 设置结果
overlay.addToMap();
// 把搜索的结果添加到地图中
overlay.zoomToSpan();
// 缩放地图,使所有Overlay都在合适的视野内 注: 该方法只对Marker类型的overlay有效
} }
class
MyPoiOverlay
extends
PoiOverlay
{
public
MyPoiOverlay(BaiduMap arg0) {
super
(arg0); } @Override
public
boolean
onPoiClick(
int
index
) { PoiResult poiResult = getPoiResult(); PoiInfo poiInfo = poiResult.getAllPoi().get(
index
);
// 得到点击的那个poi信息
String text = poiInfo.name +
","
+ poiInfo.address; Toast.makeText(getApplicationContext(), text,
0
).show(); PoiDetailSearchOption detailOption =
new
PoiDetailSearchOption(); detailOption.poiUid(poiInfo.uid);
// 设置poi的uid
poiSearch.searchPoiDetail(detailOption);
return
super
.onPoiClick(
index
); } }
3.城市内搜索
基本上是一摸一样的
private
PoiSearch poiSearch;
private
int
currentPageIndex =
0
;
private
void
search() { poiSearch = PoiSearch.newInstance(); poiSearch.setOnGetPoiSearchResultListener(
new
MyListener()); search(); PoiCitySearchOption cityOption =
new
PoiCitySearchOption(); cityOption.city(
"北京"
); cityOption.keyword(
"加油站"
); cityOption.pageNum(currentPageIndex); poiSearch.searchInCity(cityOption); }
class
MyListener
implements
OnGetPoiSearchResultListener
{ @Override
public
void
onGetPoiDetailResult(PoiDetailResult result) { } @Override
public
void
onGetPoiResult(PoiResult result) {
if
(result ==
null
|| SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error) { Toast.makeText(getApplicationContext(),
"未搜索到结果"
,
0
).show();
return
; } String text =
"共"
+ result.getTotalPageNum() +
"页,共"
+ result.getTotalPoiNum() +
"条,当前第"
+ result.getCurrentPageNum() +
"页,当前页"
+ result.getCurrentPageCapacity() +
"条"
; Toast.makeText(getApplicationContext(), text,
1
).show(); baiduMap.clear();
// 清空地图所有的 Overlay 覆盖物以及 InfoWindow
PoiOverlay overlay =
new
MyPoiOverlay(baiduMap);
// 搜索poi的覆盖物
baiduMap.setOnMarkerClickListener(overlay);
// 把事件分发给overlay,overlay才能处理点击事件
overlay.setData(result);
// 设置结果
overlay.addToMap();
// 把搜索的结果添加到地图中
overlay.zoomToSpan();
// 缩放地图,使所有Overlay都在合适的视野内 注:
// 该方法只对Marker类型的overlay有效
} } @Override
public
boolean
onKeyDown(
int
keyCode, KeyEvent event) {
if
(keyCode==KeyEvent.KEYCODE_1){ currentPageIndex++; search(); }
return
super
.onKeyDown(keyCode, event); }
class
MyPoiOverlay
extends
PoiOverlay
{
public
MyPoiOverlay(BaiduMap arg0) {
super
(arg0); } @Override
public
boolean
onPoiClick(
int
index
) { PoiResult poiResult = getPoiResult(); PoiInfo poiInfo = poiResult.getAllPoi().get(
index
);
// 得到点击的那个poi信息
String text = poiInfo.name +
","
+ poiInfo.address; Toast.makeText(getApplicationContext(), text,
0
).show();
return
super
.onPoiClick(
index
); } }
4.路线检索(驾车路线)
//驾车路线
private
void
driving(){ RoutePlanSearch newInstance = RoutePlanSearch.newInstance(); newInstance.setOnGetRoutePlanResultListener(
new
MyListener());
//驾车路线
DrivingRoutePlanOption drivingOption =
new
DrivingRoutePlanOption(); PlanNode from = PlanNode.withLocation(
new
LatLng(
22.5422870000
,
113.9804440000
));
//设置起点世界之窗
PlanNode to = PlanNode.withLocation(
new
LatLng(
22.5455910000
,
113.9880900000
));
//设置终点就附近的欢乐谷
drivingOption.from(from); drivingOption.to(to); drivingOption.policy(DrivingRoutePlanOption.DrivingPolicy.ECAR_DIS_FIRST);
//方案:最短距离 这个自己设置 比如时间短之类的
newInstance.drivingSearch(drivingOption); }
class
MyListener
implements
OnGetRoutePlanResultListener
{ @Override
public
void
onGetDrivingRouteResult(DrivingRouteResult result) {
//驾车
if
(result ==
null
|| SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error){ Toast.makeText(getApplicationContext(),
"未搜索到结果"
, Toast.LENGTH_LONG).show();
return
; }
//开始处理结果了
DrivingRouteOverlay overlay =
new
MyDrivingOverlay(baiduMap); baiduMap.setOnMarkerClickListener(overlay);
// 把事件传递给overlay
overlay.setData(result.getRouteLines().get(
0
));
// 设置线路为第一条
overlay.addToMap(); overlay.zoomToSpan(); } @Override
public
void
onGetTransitRouteResult(TransitRouteResult result) {
// 公交换乘
} @Override
public
void
onGetWalkingRouteResult(WalkingRouteResult result) {
// 步行
} }
class
MyDrivingOverlay
extends
DrivingRouteOverlay
{
public
MyDrivingOverlay(BaiduMap arg0) {
super
(arg0); } @Override
public
BitmapDescriptor getStartMarker() {
//覆写此方法以改变默认起点图标
return
BitmapDescriptorFactory.fromResource(R.drawable.icon_st); } @Override
public
BitmapDescriptor getTerminalMarker() {
//覆写此方法以改变默认终点图标
return
BitmapDescriptorFactory.fromResource(R.drawable.icon_en); } }
官方的效果图
5.6.公交换乘和步行路线,其实和驾车路线的写法是一样的这里就不写了
写的时候不知道为什么我的Overlay类来是创建不出来,所以代码拙劣的地方还请海涵
八.地图高阶——定位系统
这个相信是大家经常用到的
LocationClient和BDLocationListener首先需要打开定位图层BaiduMap
.setMyLocationEnabled
(true)
;
设置监听器LocationClient. registerLocationListener(BDLocationListener)设置定位模式baiduMap. setLocationMode(LocationMode)Hight_Accuracy,高精度定位模式:这种定位模式下,会同时使用网络定位和GPS定位,优先返回最高精度的定位结果;Battery_Saving,低功耗定位模式:这种定位模式下,不会使用GPS,只会使用网络定位(Wi-Fi和基站定位)Device_Sensors,仅用设备定位模式:这种定位模式下,不需要连接网络,只使用GPS进行定位,这种模式下不支持室内环境的定位设置定位显示模式BaiduMap
.setMyLocationConfigeration
(MyLocationConfiguration)定位数据获取:在BDLocationListener. onReceiveLocation(BDLocation result)方法中设置定位数据,baiduMap
.setMyLocationData
(MyLocationData)
;
一个GPS定位,不过必须要三颗星以上才可定位,不然是定不了的,还有一个基站地位,他其实每个基站都有一个ID,就是一个位置,查到最近基站的位置然后去服务器里请求返回位置信息,还有一个wifi定位,当你的手机连接wifi,你开始定位的时候,把wifi的地址发送到百度的服务器,服务器会把大部分wifi地址都有收录,直接返回经纬度
地址:
http://developer.baidu.com/map/index.php?title=android-locsdk/guide/v5-0
我们根据百度提供的文档去做
1.在application标签中声明service组件,每个app拥有自己单独的定位service
<
service
android:name
=
"com.baidu.location.f"
android:enabled
=
"true"
//跑在一个新的进程中
android:process
=
":remote"
>
service
>
主要用到的两个类
public
LocationClient mLocationClient;
public
BDLocationListener myListener;
private
BitmapDescriptor geo;
然后我们直接写个方法lacate();
private
void
lacate() { mLocationClient =
new
LocationClient(getApplicationContext()); myListener =
new
MyListener(); mLocationClient.registerLocationListener(myListener); LocationClientOption option =
new
LocationClientOption(); option.setLocationMode(LocationMode.Hight_Accuracy);
// 设置定位模式
option.setCoorType(
"bd09ll"
);
// 返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(
5000
);
// 设置发起定位请求的间隔时间为5000ms
option.setIsNeedAddress(
true
);
// 返回的定位结果包含地址信息
option.setNeedDeviceDirect(
true
);
// 返回的定位结果包含手机机头的方向
mLocationClient.setLocOption(option); geo = BitmapDescriptorFactory .fromResource(R.drawable.icon_geo); MyLocationConfiguration configuration =
new
MyLocationConfiguration( MyLocationConfiguration.LocationMode.FOLLOWING,
true
, geo); baiduMap.setMyLocationConfigeration(configuration);
// 设置定位显示的模式
baiduMap.setMyLocationEnabled(
true
);
// 打开定位图层
}
继续自己写个Listener
class
MyListener
implements
BDLocationListener
{ @Override
public
void
onReceiveLocation(BDLocation result) {
if
(result !=
null
) { MyLocationData data =
new
MyLocationData.Builder() .latitude(result.getLatitude()) .longitude(result.getLongitude()).build(); baiduMap.setMyLocationData(data); } } }
我们可以模拟一下使用各种方式去定位
@Override
public
boolean
onKeyDown(
int
keyCode, KeyEvent event) {
switch
(keyCode) {
case
KeyEvent.KEYCODE_1:
// 正常
baiduMap.setMyLocationConfigeration(
new
MyLocationConfiguration( MyLocationConfiguration.LocationMode.NORMAL,
true
, geo));
// 设置定位显示的模式
break
;
case
KeyEvent.KEYCODE_2:
// 罗盘
baiduMap.setMyLocationConfigeration(
new
MyLocationConfiguration( MyLocationConfiguration.LocationMode.COMPASS,
true
, geo));
// 设置定位显示的模式
break
;
case
KeyEvent.KEYCODE_3:
// 跟随
baiduMap.setMyLocationConfigeration(
new
MyLocationConfiguration( MyLocationConfiguration.LocationMode.FOLLOWING,
true
, geo));
// 设置定位显示的模式
break
;
default
:
break
; }
return
super
.onKeyDown(keyCode, event); }
百度地图算是写完一半了,为什么说只写完了一半,因为时间紧迫,里面肯定会有些错误的编写,不过思想是对的,你按照步骤来,结合你对百度API的认知,这些其实都是很简单就去实现的,这里只是作为一个抛砖引玉
后续还会持续修订更改,如有错误,欢迎点评,谢谢了!
Demo下载地址:
http://download.csdn.net/detail/qq_26787115/9379582