一. 选地图定为哪家强?

1. Google Map

  • gps坐标系,最稳定,卫星地图精细。
  • 但是在中国服务器被墙。
  • 且手机必须要有Google Service Framework。
  • 在中国不翻墙不root不可用。

2. 百度Map 和 高德Map

  • 百度,支持全球定位,功能迭代较快,地图数据加载很快。卫星地图不精细,很多户外地区放大没卫星数据。
  • 高德,稳定性不错,支持全球定位。卫星地图不精细,很多户外地区放大没卫星数据。
  • 百度,高德等国内地图都只有中国的数据。

二. 如何使用百度地图

1. 步骤

2. 实际开发步骤截图示意

① 打开官网,将鼠标移动到开发文档,选择 Android地图SDK。(在此之前,你需要登录百度账号,且成为开发者)

② 创建应用,应用类型选择AndroidSDK。

③ 填写 SHA1 和 包名,获取SHA1的方法在这里,我是在AndroidStudio中操作的。

④ 提交之后就可以看到我们的应用了。

3. 使用百度Map做一个简单的定位

① 参考官方文档

Android地图SDKAndroid定位SDK

② AndroidStudio配置

1> 下载需要的SDK,注意,一定要选择好。

2> 将解压后的 BaiduLBS_AndroidSDK_Lib 文件夹中 libs 文件夹中的内容 全部 拷贝到 工程 的 模块名.libs文件夹中。完成后在app目录下的build.gradle文件中android块中配置sourceSets标签。

3> 在工程配置中将前面添加的jar文件集成到我们的工程中。

4> 更多的配置参考:AndroidStudio配置

③ 显示地图

1> 配置AndroidManifest.xml文件

1
2
3
4
5
<application>  
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="开发者 key" />
</application>

2> 申明权限

1
2
3
4
5
6
7
8
9
<!-- 访问网络,进行地图相关业务数据请求,包括地图数据,路线规划,POI检索等 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- 读取外置存储。如果开发者使用了so动态加载功能并且把so文件放在了外置存储区域,则需要申请该权限,否则不需要 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 写外置存储。如果开发者使用了离线地图,并且数据写在外置存储区域,则需要申请该权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
1
2
3
4
5
6
7
8
9
10
11
//注意,自Android6.0起部分权限的使用需要开发者在代码中动态申请。
(API29)我之前在代码中没有动态申请GPS权限,运行后定位到太平洋哪里,所以,我动态申请了权限。

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

Toast.makeText(getApplicationContext(),"没有权限,请手动开启定位权限",Toast.LENGTH_SHORT).show();

//申请一个(或多个)权限,并提供用于回调返回的获取码(用户定义)
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 100);
}

3> 在布局文件中添加地图容器

1
2
3
4
5
<com.baidu.mapapi.map.MapView  
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />

4> 地图初始化,新建一个自定义的Application,在其onCreate方法中完成SDK的初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class DemoApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
SDKInitializer.initialize(this);
//自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
//包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
SDKInitializer.setCoordType(CoordType.BD09LL);
}
}

在AndroidManifest.xml文件中声明该Application
<application
android:name=".DemoApplication"

5> 创建地图Activity,管理MapView生命周期。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MainActivity extends Activity {  
private MapView mMapView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.bmapView);
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
}

6> 简单的示意图

④ 显示定位

1> 配置AndroidManifest.xml文件,申明权限以及申明Service。

1
2
3
4
<!-- 这个权限用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- 这个权限用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
1
2
3
<service android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote"/>

2> 开启地图的定位层

1
mBaiduMap.setMyLocationEnabled(true);

3> 注册LocationListener监听器

1
2
3
//注册LocationListener监听器
MyLocationListener myLocationListener = new MyLocationListener();
mLocationClient.registerLocationListener(myLocationListener);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
//mapView 销毁后不在处理新接收的位置
if (location == null || mMapView == null){
return;
}

//此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
//以下只列举部分获取经纬度相关(常用)的结果信息
//更多结果信息获取说明,请参照类参考中BDLocation类中的说明

//获取纬度信息
double latitude = location.getLatitude();
//获取经度信息
double longitude = location.getLongitude();
//获取定位精度,默认值为0.0f
float radius = location.getRadius();
//获取经纬度坐标类型,以LocationClientOption中设置过的坐标类型为准
String coorType = location.getCoorType();
//获取定位类型、定位错误返回码,具体信息可参照类参考中BDLocation类中的说明
int errorCode = location.getLocType();

Log.d(TAG,"纬度:"+latitude+" 经度:"+longitude);

//定义Maker坐标点
LatLng point = new LatLng(latitude, longitude);
//构建Marker图标
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.marker);
//构建MarkerOption,用于在地图上添加Marker
OverlayOptions option = new MarkerOptions()
.position(point)
.icon(bitmap);
//在地图上添加Marker,并显示
mBaiduMap.addOverlay(option);

//定义将要发生的状态
MapStatus mMapStatus = new MapStatus.Builder()
.target(point)
.zoom(18)
.build();
//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
//改变地图状态
mBaiduMap.setMapStatus(mMapStatusUpdate);
}
}

4> 构造地图数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//通过LocationClientOption设置LocationClient相关参数
LocationClientOption option = new LocationClientOption();
//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
//设置坐标类型
option.setCoorType("bd09ll");
//可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
option.setScanSpan(1000);
//可选,设置是否需要地址信息,默认不需要
option.setIsNeedAddress(true);
//可选,设置是否需要地址描述
option.setIsNeedLocationDescribe(true);
//可选,设置是否需要设备方向结果
option.setNeedDeviceDirect(false);
//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
option.setLocationNotify(true);
//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
option.setIgnoreKillProcess(true);
//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
option.setIsNeedLocationDescribe(true);
//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
option.setIsNeedLocationPoiList(true);
//可选,默认false,设置是否收集CRASH信息,默认收集
option.SetIgnoreCacheException(false);
//可选,默认false,设置是否开启Gps定位
option.setOpenGps(true);
//可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
option.setIsNeedAltitude(false);
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者,该模式下开发者无需再关心定位间隔是多少,定位SDK本身发现位置变化就会及时回调给开发者
option.setOpenAutoNotifyMode();
//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者
//需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
//设置locationClientOption
mLocationClient.setLocOption(option);

5> 开启地图定位

1
2
//开启地图定位图层
mLocationClient.start();

6> 管理生命周期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
protected void onResume() {
mMapView.onResume();
super.onResume();
}

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

@Override
protected void onDestroy() {
mLocationClient.stop();
mBaiduMap.setMyLocationEnabled(false);
mMapView.onDestroy();
mMapView = null;
super.onDestroy();
}

7> 运行效果

⑤ 源代码

BaiduMap

参考文章

手把手教你实现百度基础地图+定位功能+设置中心点+添加Marker