Android问题集锦
3.1 定位、坐标相关
3.1.1 API如何获取定位信息?
说明:此部分是针对1.3.5及以前版本的说明,自2.0.0版本以后,定位功能已从Android SDK中分离,开发者在使用定位功能时,请具体参考定位SDK。
在百度地图移动版API中,我们提供一个重要的特色功能:定位,通过这个功能,能获取到用户当前所在位置。
在程序中,如果使用此功能,必须注册GPS和网络的使用权限。
在获取用户位置时,优先使用GPS进行定位;如果GPS定位没有打开或者没有可用位置信息,则会通过判断网络是否连接(即确认手机是否能上网,不论是连接2G/3G或Wi-Fi网络),如果是,则通过请求百度网络定位服务,返回网络定位结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。
目前系统自带的网络定位服务精度低,且服务不稳定、精度低,并且从未来的趋势看,基站定位是不可控的(移动公司随时可能更改基站编号以垄断定位服务),而Wi-Fi定位则不然,它是一种精度更高、不受管制的定位方法。国内其它使用Wi-Fi定位的地图软件,Wi-Fi定位基本不可用,百度的定位服务量化指标优秀,网络接口返回速度快(服务端每次定位响应时间50毫秒以内),平均精度70米,其中Wi-Fi精度40米左右,基站定位精度200米左右,覆盖率98%,在国内处于一枝独秀的地位。
3.1.2 如何得到定位的坐标和地址?
说明: 自2.0.0版本开始,获取定位坐标的方法请参考定位SDK中的说明,如下获取定位坐标的方法只针对1.3.5及以前的版本有效。
使用MKLocationManager 类的requestLocationUpdates 注册位置监听事件,在重写的回调函数onLocationChanged中,可获得定位的坐标(详见BMapApiDemoMain例程的MyLocation.java),通过调用MKSearch类的reverseGeocode接口,得到地址。
-
1. @Override
-
2.
public
void onLocationChanged
( Location location
)
{
-
3.
if
( location
!=
null
)
{
-
4.
pt.
setLatitudeE6
(
(
int
)
(location.
getLatitude
(
)
*1e6
)
)
;
-
5.
pt.
setLongtitudeE6
(
(
int
)
(location.
getLongtitude
(
)
*1e6
)
)
;
-
6.
mSearch.
reverseGeocode
(pt
)
;
-
7.
}
-
8.
}
-
9.
public
void onGetAddrResult
( MKAddrInfo res,
int error
)
{
-
10.
if
( error
!=
0
)
{
-
-
12.
return
;
-
13.
}
-
-
15.
res.
geoPt.
getlatitudeE6
(
)
/ 1e6,
-
16.
res.
geoPt.
getLongtitudeE6
/ 1e6,
-
17.
res.
addressComponents.
city
+
-
18.
res.
addressComponents.
district
+
-
19.
res.
addressComponents.
street
)
;
-
20.
}
3.1.3 如何让我的地图自动定位?
说明: 此部分是针对1.3.5及以前版本的说明,自2.0.0版本以后,定位功能已从Android SDK中分离,开发者在实现自动定位操作时,请参考定位SDK中的具体说明
首先在程序中打开相关的权限,然后将MyLocationOverlay实例添加到MapView中,并调用enableMyLocation方法,即可实现当前位置的显示,如果想让地图跟随当前位置移动,需要继承MyLocationOverlay并实现其onLocationChanged方法,调用MapView.getController().animateTo()方法移动地图位置。
3.1.4 如何计算两点之间距离?
路线规划提供了获取路线距离的方法,见MKRoutePlan 类的 getDistance 方法。
如果是计算任意两点的距离,自2.0.0版本开始,Android SDK为开发者提供了计算距离的接口(DistanceUtil),具体使用方法如下:
1.GeoPoint p1LL = new GeoPoint(39971802, 116347927);
2.GeoPoint p2LL = new GeoPoint(39892131, 116498555);
3.double distance = DistanceUtil.getDistance(p1LL, p2LL);
如果开发者使用的是1.3.5及以前的版本,在计算任意两点之前的距离时,有如下两种方法:一种利用勾股定理计算,适用于两点距离很近的情况;一种按标准的球面大圆劣弧长度计算,适用于距离较远的情况。
-
1.
static
double DEF_PI
=
3.14159265359
;
// PI
-
2.
static
double DEF_2PI
=
6.28318530712
;
// 2*PI
-
3.
static
double DEF_PI180
=
0.01745329252
;
// PI/180.0
-
4.
static
double DEF_R
=
6370693.5
;
// radius of earth
-
5.
public
double GetShortDistance
(
double lon1,
double lat1,
double lon2,
double lat2
)
-
6.
{
-
7.
double ew1, ns1, ew2, ns2
;
-
8.
double dx, dy, dew
;
-
9.
double distance
;
-
10.
// 角度转换为弧度
-
11.
ew1
= lon1
* DEF_PI180
;
-
12.
ns1
= lat1
* DEF_PI180
;
-
13.
ew2
= lon2
* DEF_PI180
;
-
14.
ns2
= lat2
* DEF_PI180
;
-
15.
// 经度差
-
16.
dew
= ew1
- ew2
;
-
17.
// 若跨东经和西经180 度,进行调整
-
18.
if
(dew
> DEF_PI
)
-
19.
dew
= DEF_2PI
- dew
;
-
20.
else
if
(dew
<
-DEF_PI
)
-
21.
dew
= DEF_2PI
+ dew
;
-
-
23.
dy
= DEF_R
*
(ns1
- ns2
)
;
// 南北方向长度(在经度圈上的投影长度)
-
24.
// 勾股定理求斜边长
-
-
26.
return distance
;
-
27.
}
-
28.
public
double GetLongDistance
(
double lon1,
double lat1,
double lon2,
double lat2
)
-
29.
{
-
30.
double ew1, ns1, ew2, ns2
;
-
31.
double distance
;
-
32.
// 角度转换为弧度
-
33.
ew1
= lon1
* DEF_PI180
;
-
34.
ns1
= lat1
* DEF_PI180
;
-
35.
ew2
= lon2
* DEF_PI180
;
-
36.
ns2
= lat2
* DEF_PI180
;
-
37.
// 求大圆劣弧与球心所夹的角(弧度)
-
-
39.
// 调整到[-1..1]范围内,避免溢出
-
40.
if
(distance
>
1.0
)
-
41.
distance
=
1.0
;
-
42.
else
if
(distance
<
-
1.0
)
-
43.
distance
=
-
1.0
;
-
44.
// 求大圆劣弧长度
-
-
46.
return distance
;
-
47.
}
-
48.
double mLat1
=
39.90923
;
// point1纬度
-
49.
double mLon1
=
116.357428
;
// point1经度
-
50.
double mLat2
=
39.90923
;
// point2纬度
-
51.
double mLon2
=
116.397428
;
// point2经度
-
52.
double distance
= GetShortDistance
(mLon1, mLat1, mLon2, mLat2
)
;
3.1.5 点击MapView上一点,如何获取该点坐标?
通过继承MapView类重写onTouchEvent方法来获取点击屏幕的位置,再通过接口Projection的 fromPixels 方法将点击位置转换为该点的地址坐标,并且将地图空间bMapView的类型由com.baidu.mapapi.MapView改为子类类型,本例中为com.baidu.mapapi.demo.MapViewTest具体代码如下:
-
1.
MapViewTest mapView
=
(MapViewTest
)findViewById
(R.
id.
bmapView
)
;
-
2.
class MapViewTest
extends MapView
-
3.
{
-
-
5.
{
-
6.
super
(context
)
;
-
7.
}
-
-
9.
{
-
10.
super
( context, attrs
)
;
-
11.
}
-
-
13.
{
-
14.
super
( context, attrs,defStyle
)
;
-
15.
}
-
16. @Override
-
17.
public
boolean onTouchEvent
(MotionEvent event
)
-
18.
{
-
19.
//获得屏幕点击的位置
-
20.
int x
=
(
int
)event.
getX
(
)
;
-
21.
int y
=
(
int
)event.
getY
(
)
;
-
22.
//将像素坐标转为地址坐标
-
23.
GeoPoint pt
=
this.
getProjection().
fromPixels
(x,y
)
;
-
24.
return
super.
onTouchEvent
(event
)
;
-
25.
}
-
26.
}
3.1.6 百度地图地址解析服务Geocoder如何使用?
地址解析服务在MKSearch类中有两个接口:reverseGeocode、geocode。
初始化搜索类MKSearch并注册结构监听对象MKSearchListener:
-
1.
//初始化搜索模块,注册事件监听
-
2.
mSearch
=
new MKSearch
(
)
;
-
3.
mSearch.
init
(app.
mBMapMan,
new MySearchListener
(
)
)
;
实现MySearchListener的onGetAddrResult获取得到的地址信息
-
1. @Override
-
2.
public
void onGetAddrResult
( MKAddrInfo res,
int error
)
{
-
3.
if
( error
!=
0
)
{
-
-
5.
return
;
-
6.
}
-
-
8.
res.
geoPt.
getlatitudeE6
(
)
/ 1e6,
-
9.
res.
geoPt.
getLongtitudeE6
/ 1e6,
-
10.
res.
addressComponents.
city
+
-
11.
res.
addressComponents.
district
+
-
12.
res.
addressComponents.
street
)
;
-
13.
}
geocode:根据地址名称获取地址信息:
-
1.
mSearch.
geocode
(
"天安门",
"北京"
)
;
reverseGeocode:根据地理坐标点获取地址:
-
1.
GeoPoint ptCenter
=
new GeoPoint
(
39904965,
116327764
)
;
-
2.
mSearch.
reverseGeocode
(ptCenter
)
;
3.1.7 百度地图与google地图坐标差异?
国际经纬度坐标标准为WGS-84,国内必须至少使用国家测绘局制定的GCJ-02对地理位置进行首次加密。百度地图在此基础上,进行了BD-09二次加密措施,因此百度地图对外接口的坐标系并不是GPS采集的真实经纬度,而是有较大偏移。
3.2 搜索、覆盖物相关
3.2.1 如何获得驾车/步行/公交路线距离?
在搜索结果的回调函数中,可以返回驾车/步行/公交路线方案,路线距离可根据方案结构数据获得:
驾车路线:
-
1.
public
void onGetDrivingRouteResult
(MKDrivingRouteResult res,
-
2.
int error
)
{
-
3.
// 错误号可参考MKEvent中的定义
-
4.
if
(error
!=
0
|| res
==
null
)
{
-
5.
Toast.
makeText
(RoutePlan.
this,
"抱歉,未找到结果", Toast.
LENGTH_SHORT
).
show
(
)
;
-
6.
return
;
-
7.
}
-
8.
//获得路线距离
-
9.
int distance
= res.
getPlan
(
0
).
getRoute
(
0
).
getDistance
(
)
;
-
10.
RouteOverlay routeOverlay
=
new RouteOverlay
(RoutePlan.
this, mMapView
)
;
-
11.
// 此处仅展示一个方案作为示例
-
12.
routeOverlay.
setData
(res.
getPlan
(
0
).
getRoute
(
0
)
)
;
-
13.
mMapView.
getOverlays
(
).
clear
(
)
;
-
14.
mMapView.
getOverlays
(
).
add
(routeOverlay
)
;
-
15.
mMapView.
invalidate
(
)
;
//2.0.0及以上版本请使用mMapView.refresh();
-
16.
mMapView.
getController
(
).
animateTo
(res.
getStart
(
).
pt
)
;
-
17.
}
公交路线:
-
1.
public
void onGetTransitRouteResult
(MKTransitRouteResult res,
-
2.
int error
)
{
-
3.
// 错误号可参考MKEvent中的定义
-
4.
if
(error
!=
0
|| res
==
null
)
{
-
5.
Toast.
makeText
(RoutePlan.
this,
"抱歉,未找到结果", Toast.
LENGTH_SHORT
).
show
(
)
;
-
6.
return
;
-
7.
}
-
8.
//获得路线距离
-
9.
int distance
= res.
getPlan
(
0
).
getDistance
(
)
;
-
10.
TransitOverlay routeOverlay
=
new TransitOverlay
(RoutePlan.
this, mMapView
)
;
-
11.
// 此处仅展示一个方案作为示例
-
12.
routeOverlay.
setData
(res.
getPlan
(
0
).
getRoute
(
0
)
)
;
-
13.
mMapView.
getOverlays
(
).
clear
(
)
;
-
14.
mMapView.
getOverlays
(
).
add
(routeOverlay
)
;
-
15.
mMapView.
invalidate
(
)
;
//2.0.0及以上版本请使用mMapView.refresh();
-
16.
mMapView.
getController
(
).
animateTo
(res.
getStart
(
).
pt
)
;
-
17.
}
步行路线:
-
1.
public
void onGetWalkingRouteResult
(MKWalkingRouteResult res,
-
2.
int error
)
{
-
3.
// 错误号可参考MKEvent中的定义
-
4.
if
(error
!=
0
|| res
==
null
)
{
-
5.
Toast.
makeText
(RoutePlan.
this,
"抱歉,未找到结果", Toast.
LENGTH_SHORT
).
show
(
)
;
-
6.
return
;
-
7.
}
-
8.
//获得路线距离
-
9.
int distance
= res.
getPlan
(
0
).
getRoute
(
0
).
getDistance
(
)
;
-
10.
RouteOverlay routeOverlay
=
new RouteOverlay
(RoutePlan.
this, mMapView
)
;
-
11.
// 此处仅展示一个方案作为示例
-
12.
routeOverlay.
setData
(res.
getPlan
(
0
).
getRoute
(
0
)
)
;
-
13.
mMapView.
getOverlays
(
).
clear
(
)
;
-
14.
mMapView.
getOverlays
(
).
add
(routeOverlay
)
;
-
15.
mMapView.
invalidate
(
)
;
//2.0.0及以上版本请使用mMapView.refresh();
-
16.
mMapView.
getController
(
).
animateTo
(res.
getStart
(
).
pt
)
;
-
17.
}
3.2.2 POI查询结果每页显示几个,如何翻页?
POI检索结果每页容量默认情况下为10,翻页功能通过MKSearch类的goToPoiPage实现,该方法是异步函数,搜索成功后会调用注册的事件处理函数onGetPoiResult 返回查询页的结果,此接口只针对最后一次POI搜索进行翻页检索,即完成一次POI搜索后,调用此方法进行翻页。
3.2.3 如何设置POI检索每页显示容量?
POI检索结果每页容量可以通过MKSearch类的setPoiPageCapacity接口进行设置,支持1-50 ,默认情况下为10。也可以通过getPoiPageCapacity 获得当前POI搜索结果的每页容量。
3.2.4 路线规划不支持模糊搜索?
目前不支持模糊搜索,需要输入准确的站名;当起点/终点不是公交站/地铁站时,需要在节点信息中输入地址坐标。
-
1.
//百度大厦坐标
-
2.
GeoPoint pt1
=
new GeoPoint
(
40057030,
116307845
)
;
-
3.
//天安门广场
-
4.
GeoPoint pt2
=
new GeoPoint
(
39912725,
116404008
)
;
-
5.
MKPlanNode stNode
=
new MKPlanNode
(
)
;
-
6.
stNode.
name
=
"百度大厦"
;
-
7.
stNode.
pt
= pt1
;
-
8.
MKPlanNode enNode
=
new MKPlanNode
(
)
;
-
9.
enNode.
name
=
"天安门广场"
;
-
10.
enNode.
pt
= pt2
;
-
11.
mSearch.
transitSearch
(
"北京", stNode, enNode
)
;
获取坐标的方法可以通过关键字执行poi搜索,得到poi信息后取出地址坐标信息,再进行路线规划搜索。
-
1.
mSearch.
poiSearchInCity
(
"北京",
"百度大厦"
)
;
-
2.
pubic
void onGetPoiResult
(MKPoiResult res,
int type,
int error
)
{
-
3.
if
(error
!=
0
|| res
==
null
)
{
-
4.
Toast.
makeText
(PoiSearch.
this,
"抱歉,未找到结果", Toast.
LENGTH_LONG
).
show
(
)
;
-
5.
return
;
-
6.
}
-
7.
//本例中取第一个poi点
-
8.
GeoPoint pt
= res.
getPoi
(
0
).
pt
;
-
9.
}
3.2.5 如何在一个地图上显示多条导航路线?
以公交路线规划为例:
-
1.
public
void onGetTransitRouteResult
(MKTransitRouteResult res,
-
2.
int error
)
{
-
3.
if
(error
!=
0
|| res
==
null
)
{
-
4.
Toast.
makeText
(RoutePlan.
this,
"抱歉,未找到结果", Toast.
LENGTH_SHORT
).
show
(
)
;
-
5.
return
;
-
6.
}
-
7.
int planNum
= res.
getNumPlan
(
)
;
//获得路线方案个数
-
8.
for
(
int i
=
0
;i
<planNum
;i
++
)
-
9.
{
-
10.
TransitOverlay routeOverlay
=
new TransitOverlay
(RoutePlan.
this, mMapView
)
;
-
11.
routeOverlay.
setData
(res.
getPlan
(i
)
)
;
-
12.
mMapView.
getOverlays
(
).
add
(routeOverlay
)
;
-
13.
}
-
14.
-
15.
mMapView.
invalidate
(
)
;
//2.0.0及以上版本请使用mMapView.refresh();
-
16.
mMapView.
getController
(
).
animateTo
(res.
getStart
(
).
pt
)
;
-
17.
}
3.2.6 搜索结果标注如何自定义点击处理?
继承PoiOverlay类重写OnTap方法,具体参考如下代码:
定义PoiOverlayTest类继承PoiOverlay类,在类中重写OnTap方法响应自定义处理,再执行父类的OnTap事件
-
1.
class PoiOverItemT
extends PoiOverlay
{
-
2.
public PoiOverItemT
(Activity activity, MapView mapView
)
{
-
3.
super
(activity, mapView
)
;
-
4.
}
-
5. @Override
-
6.
protected
boolean onTap
(
int i
)
{
-
7.
//自定义点击处理事件
-
8.
//
-
9.
//
-
10.
//
-
11.
return
super.
onTap
(i
)
;
//响应父类的点击事件
-
12.
}
-
13.
}
在Poi搜索回调函数中定义PoiOverlayTest类对象,设置结果数据,并绘制在地图上,这事点击poi点即可响应自定义的处理事件
-
1.
pubic
void onGetPoiResult
(MKPoiResult res,
int type,
int error
)
{
-
2.
if
(error
!=
0
|| res
==
null
)
{
-
3.
Toast.
makeText
(PoiSearch.
this,
"抱歉,未找到结果", Toast.
LENGTH_LONG
).
show
(
)
;
-
4.
return
;
-
5.
}
-
6.
if
(res.
getCurrentNumPois
(
)
>
0
)
-
7.
{
-
8.
//将poi结果显示在地图上,PoiOverlayTest类继承PoiOverlay类
-
9.
PoiOverlayTest poiOverlay
=
new PoiOverlayTest
(PoiSearch.
this, mMapView
)
;
-
10.
poiOverlay.
setData
(res.
getAllPoi
(
)
)
;
-
11.
mMapView.
getOverlays
(
).
clear
(
)
;
-
12.
mMapView.
getOverlays
(
).
add
(poiOverlay
)
;
-
13.
mMapView.
invalidate
(
)
;
//2.0.0及以上版本请使用mMapView.refresh();
-
14.
}
-
15.
}
3.2.7 POI是否支持按分类检索?
支持分类搜索,例如mSearch.poiSearchInCity("北京", "娱乐");得到的搜索结果中是和娱乐相关的地点,例如保龄球馆、娱乐广场等。
3.2.8 如何清除覆盖物?
通过getOverlays获得MapView的所有覆盖物,并清除。
-
1.
pubic
void onGetPoiResult
(MKPoiResult res,
int type,
int error
)
{
-
2.
if
(error
!=
0
|| res
==
null
)
{
-
3.
Toast.
makeText
(PoiSearch.
this,
"抱歉,未找到结果", Toast.
LENGTH_LONG
).
show
(
)
;
-
4.
return
;
-
5.
}
-
6.
if
(res.
getCurrentNumPois
(
)
>
0
)
-
7.
{
-
8.
//将poi结果显示在地图上
-
9.
PoiOverlay poiOverlay
=
new PoiOverlay
(PoiSearch.
this,
-
10.
mMapView
)
;
-
11.
poiOverlay.
setData
(res.
getAllPoi
(
)
)
;
-
12.
//添加新的Overlay之前清除之前的所有Overlay
-
13.
mMapView.
getOverlays
(
).
clear
(
)
;
-
14.
mMapView.
getOverlays
(
).
add
(poiOverlay
)
;
-
15.
mMapView.
invalidate
(
)
;
//2.0.0及以上版本请使用mMapView.refresh();
-
16.
}
-
17.
}
3.2.9 如何修改标注显示的图片?
详情参见BMapApiDemoMain中的ItemizedOverlayDemo.java,demo中Overlay使用的标注图片是资源文件夹中的iconmarka.png,用户可随意修改使用的图片资源。
3.2.10 标注点的气泡内容如何修改?
Overlay点击的气泡是通过在应用上层添加一个自定义的view实现的,具体参考BMapApiDemoMain例程中的ItemizedOverlayDemo,通过继承ItemizedOverlay<OverlayItem>实现重写标注点的点击响应事件,弹出泡泡的内容是通过mapView.addView添加了一个popview,见layout下的popview.xml,例程中的popview添加的是一个imageview,用户可以任意改变imageview显示的图片,或者放置n个imageview在popview中,也可以修改为EditText等控件。
3.2.11 添加覆盖物后地图上不显示?
使用mMapView.getOverlays().add()添加overlay后,需要调用mMapView.invalidate();(2.0.0及以上版本请使用mMapView.refresh();)来刷新显示overlay。
3.2.12 使用routeOverlay出现crash情况?
确保返回有搜索结果,并且确保执行RouteOverlay 类的setData方法,之后再addOverlay。
3.3 离线地图相关
3.3.1 如何下载离线地图?
请到官网下载:http://shouji.baidu.com/map/map.html?from=3052
其中,百度地图Android SDK V1.3.5及以前版本请下载旧版离线地图,下载入口请参考:http://www.cnblogs.com/milkmap/archive/2012/05/21/2511928.html提供的方法。
百度地图Android SDK V2.0.0请下载新版离线地图,即直接进入上述下载地址,选择对应手机品牌,机型,即可。
离线地图下载完毕,请参考开发指南进行导入。
3.3.2 离线地图怎么使用?
到官网下载离线地图包http://shouji.baidu.com/map/map.html?from=3052;
离线地图分新版和旧版,新版是矢量地图,旧版是栅格地图,Android SDK自2.0.0版本开始仅支持矢量版离线地图,请使用2.0.0及以上版本的开发者在下载离线地图时注意选择矢量版;使用1.3.5及以前版本的开发者,在使用离线地图功能时请下载旧版离线地图,即栅格版地图。
新版与旧版离线地图的下载方法请参看3.3.1常见问题介绍的下载方法。
具体安装指南如下:
比如,选择下载北京市的离线地图:
解压后,有两个文件。一个是BaiduMap,一个是安装说明。
不要管安装说明,把BaiduMap打开,能看到Mapdata文件夹。拷贝这个文件夹。
将Mapdata文件夹拷贝到手机SD卡的BaiduMapSdk文件夹根目录下。
找到主java文件,并在activity里申明变量。
-
MKOfflineMap mOffline
=
null
;
//离线地图变量
然后在onCreate函数里写离线地图初始化的代码,具体请参考BMapApiDemoMain例程中的OfflineDemo.java:
-
/** 离线地图初始化 **/ mOffline
=
new MKOfflineMap
(
)
;
-
2.
mOffline.
init
(mBMapMan,
new MKOfflineMapListener
(
)
{
-
3.
public
void onGetOfflineMapState
(
int type,
int state
)
{
-
4.
switch
(type
)
{
-
5.
case MKOfflineMap.
TYPE_DOWNLOAD_UPDATE
:
-
6.
{
-
7.
MKOLUpdateElement update
= mOffline.
getUpdateInfo
(state
)
;
-
8.
//mText.setText(String.format("%s : %d%%", update.cityName, update.ratio));
-
9.
}
-
10.
break
;
-
11.
case MKOfflineMap.
TYPE_NEW_OFFLINE
:
-
-
13.
break
;
-
14.
case MKOfflineMap.
TYPE_VER_UPDATE
:
-
-
16.
break
;
-
17.
}
-
18.
}
-
19.
}
-
20.
)
;
-
21.
/** 离线地图导入离线包 **/
-
22.
int num
= mOffline.
scan
(
)
;
导入成功后运行地图,可以看到不联网状态下的地图展示效果
Android SDK 2.0.0版本离线功能的使用方法请参考《开发指南》中的相关章节,此处不再赘述。
3.3.3 离线地图下载失败怎么办?
下载离线地图请确保设备中有SD卡,使用MKOfflineMap类,在初始化init时,会联网下载相关配置文件,请确保配置文件全部下载完毕后开始离线地图的下载(配置文件位于SD卡根目录下的BaiduMapSDK文件夹内,共五个dat文件),否则会因为找不到配置文件而返回下载失败,之后使用start开始下载制定城市ID的离线地图。
3.4 定位相关
说明: 此部分是针对1.3.5及以前版本的说明,自2.0.0版本以后,定位功能已从Android SDK中分离,开发者在使用定位功能时,请具体参考定位SDK。
3.4.1 通过Wi-Fi和移动网络定位得到的数据精度偏差较大?
通常Wi-Fi信号覆盖范围在几十米到几百米,通过Wi-Fi网络定位的设备距离Wi-Fi信号源不范围也就在几十米到几百米,同理,移动网络的覆盖范围在一公里甚至更远,因此可能产生的误差也越大。
3.4.2 如何获得定位的位置信息?(定位返回的信息有哪些?)
说明: 自2.0.0版本开始,获取定位坐标的方法请参考定位SDK中的说明,如下获取定位坐标的方法只针对1.3.5及以前的版本有效
通过MKLocationManager注册或者移除定位监听器,监听返回的是android系统的Location类对象,坐标为百度坐标。具体如下:
-
1.
//获得定位服务
-
2.
mLocationManager
= mBMapMan.
getLocationManager
(
)
;
-
3.
//设置监听间隔
-
4.
mLocationManager.
setNotifyInternal
(
10,
5
)
;
-
5.
//定义定位监听事件
-
6.
LocationListener mLocationListener
=
new LocationListener
(
)
-
7.
{
-
8. @Override
-
9.
public
void onLocationChanged
(Location location
)
-
10.
{
-
11.
if
(location
!=
null
)
-
12.
{
-
-
14.
}
-
15.
}
-
16.
}
-
17.
//注册监听事件
-
18.
mLocationManager.
requestLocationUpdates
(mLocationListener
)
;
-
19.
//不需要定位时移除监听事件
-
20.
mLocationManager.
removeUpdates
(mLocationListener
)
;
3.4.3 持续定位如何关闭?
使用MKLocationManager类的requestLocationUpdates 来注册位置监听,用 removeUpdates 来取消位置监听。
-
1.
public
void stopLoc
(
)
-
2.
{
-
3.
BMapApiDemoApp app
=
(BMapApiDemoApp
)
this.
getApplication
(
)
;
-
4.
//移除listener
-
5.
app.
mBMapMan.
getLocationManager
(
).
removeUpdates
(mLocationListener
)
;
-
6.
}
-
7.
public
void startLoc
(
)
-
8.
{
-
9.
BMapApiDemoApp app
=
(BMapApiDemoApp
)
this.
getApplication
(
)
;
-
10.
// 注册listener
-
11.
app.
mBMapMan.
getLocationManager
(
).
requestLocationUpdates
(mLocationListener
)
;
-
12.
}
3.4.4 支持台湾、香港及其他大陆地区外的定位吗?
支持港澳,暂不支持台湾及境外。
3.5 地图相关
3.5.1 如何控制地图缩放级别?
使用MapController 类的setZoom方法。
Eg:mapView.getController().setZoom(13);支持缩放级别范围为3-18
3.5.2 支持三维效果的地图吗?
自2.0.0版本起,Android SDK仅支持矢量版地图,当地图放大到一定级别后,底图的显示将支持3D效果;
Android SDK 1.3.5及以前的版本依旧使用的是栅格版地图,故无法支持底图的三维效果,有3D效果显示需要的开发者请升级SDK版本到2.0.0及以上。
3.5.3 目前支持多少种地图类型?
目前的SDK底图为矢量图(有栅格图使用要求的开发者请使用1.3.5及以前版本的SDK),类型包括普通地图、卫星图、实时交通图
3.5.4 地图初始显示如何设置中心点?
使用MapController 类的setCenter方法。
-
1.
GeoPpoint point
=
new GeoPoint
(
(
int
)
(
31.764
*1e6
),
(
int
)
(
119.953
*1e6
)
)
;
-
2.
mMapView.
getController
(
).
setCenter
(point
)
;
3.5.5 从一个MapActivity跳转到另一个MapActivity如何实现?
说明: 此部分是针对1.3.5及以前版本的说明,自2.0.0版本以后,开发者新建立的activity只需集成Android系统的Activity即可
核心代码是:
-
1.
Intent intent =
null
;
-
2.
intent =
new Intent
(MapActivity1.
this, MapActivity2.
class
)
;
-
3.
this.
startActivity
(intent
)
;
只用一个BMapManager管理类对象,在进入第二个MapActivity时不要重新初始化BMapManager管理类对象,只在离开页面时stop,进入页面时start。
3.5.6 Mapview嵌套在Linearlayout中,从其他页面切回地图页面时黑屏?
如果在移出Mapview时调用了LinearLayout的removeAllViews方法,需要再切回地图页面时调用MapActivity类的initMapActivity方法重新加载地图控件。
3.6 其他
3.6.1 为何我的百度地图不显示底图?
检查在程序中是否使用了正确的Key,有没有打开使用网络连接的权限,以及手机有没有连接互联网。
3.6.2 总是返回网络错误是怎么回事?
首先请确认设备已联网且网络畅通,再次需确认app工程中AndroidManifest.xml设置是否加入了网络权限
3.6.3 Key的申请和AppName有关系吗?
每个应用申请一个key,可以用在不同移动平台上的相同应用中。
3.6.4 BMapManager对象初始化几次?
管理类对象只初始化一次,建议在Application里生成BMapManager对象并初使化,在程序退出时调用destory,在需要使用sdk功能的activity的onCreate里调用start, onDestroy调用stop,或者onResume/onPause分别调用start和stop。
3.6.5 为何我的程序在不混淆之前可以运行,混淆之后不能运行了?
如果您使用proguard进行混淆,请在您的混淆配置文件中添加如下语句:
-keep class com.baidu.mapapi.** {*;}
其他混淆工具也请进行与此类似的配置,指定对mapapi中的类和方法不进行混淆。
3.6.6 目前有哪些城市具有实时交通图?
目前已有31个城市开通,分别为南京,广州,重庆,东莞,长春,台州,福州,金华,北京,常州,杭州,温州,大连,南昌,宁波,沈阳,中山,珠海,佛山,泉州,石家庄,成都,青岛,深圳,武汉,乌鲁木齐,长沙,上海,天津,无锡,厦门。之后其他城市还会陆续开通。