目录
- 准备工作
- 1 注册百度开发者账号
- 2 创建应用并获取密钥
- 3 下载百度地图 SDK
- Android Studio 项目配置
- 1 添加 SDK Jar 包
- 2 添加 so 库文件
- 3 配置 AndroidManifest.xml
- 4 配置 build.gradle (Module: app)
- 在布局文件中添加地图控件
- 在 Activity 中初始化地图
- 核心功能实现
- 1 实现基本地图显示
- 2 获取并显示当前位置 (定位)
- 3 在地图上添加标记点
- 4 绘制折线/多边形
- 5 路线规划 (驾车)
- 完整代码示例
- 常见问题与注意事项
- 进阶学习
准备工作
在开始编码之前,你必须完成以下步骤,这是使用百度地图 SDK 的前提。

1 注册百度开发者账号
- 访问 百度地图开放平台。
- 点击右上角的“登录/注册”,使用你的百度账号登录,如果没有账号,需要先注册。
2 创建应用并获取密钥
密钥是你的应用调用百度地图服务的唯一凭证。
- 登录后,进入“控制台”。
- 在左侧菜单栏选择“应用管理” -> “我的应用”。
- 点击“创建应用”按钮。
- 填写应用信息:
- 应用名称: 填写你的应用名称,"我的第一个百度地图App"。
- 应用类型: 选择
Android SDK。 - 发布版 SHA1: 这是关键!你需要获取你发布版应用的签名 SHA1 值。
- 开发版 SHA1: 同样需要,用于在手机上调试。
- 如何获取 SHA1?
- 方法一 (推荐): 在 Android Studio 中,打开你的项目,然后点击菜单
Build->Generate Signed Bundle / APK。 - 选择
APK,点击Next。 - 在
Key store path处,选择你的签名文件(如果还没有,需要先创建一个,记住密码!)。 - 在下方
Signature versions中选择v1(Jar signing) 或v2(Full APK signing) 都可以。 - 点击
Finish,Android Studio 会生成 APK,并在底部的Build输出窗口中打印出完整的 SHA1 值,复制它。 - 使用命令行,找到你的
debug.keystore文件位置(通常在~/.android/目录下),然后运行:keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey
输入密码
android,即可看到 SHA1。
- 方法一 (推荐): 在 Android Studio 中,打开你的项目,然后点击菜单
- 填写包名: 填写你 Android 项目的包名,
com.example.baidumapdemo。 - 创建应用: 点击“提交”按钮,创建成功后,你会看到一个应用列表,其中包含你刚刚创建的应用。
- 获取 AK (Access Key): 在你的应用列表中,找到对应的应用,复制
API Key,这个 AK 就是你在代码中需要使用的密钥。
3 下载百度地图 SDK
- 回到 百度地图开放平台,点击“开发文档” -> “Android SDK” -> “下载”。
- 选择你需要的 SDK 服务,我们至少需要:
- 基础地图 SDK
- 定位 SDK
- 搜索 SDK
- 路线规划 SDK
- 下载后,你会得到一个压缩包,里面包含了
jar包、so库文件、以及demo示例。
Android Studio 项目配置
将下载好的 SDK 集成到你的 Android Studio 项目中。
1 添加 SDK Jar 包
- 解压下载的 SDK 压缩包。
- 找到
android目录下的BaiduLBS_Android.jar文件。 - 将这个
jar文件复制到你的 Android 项目的app/libs目录下。 - 在 Android Studio 中,右键点击
libs目录 ->Add As Library...,确保勾选并添加到你的app模块中。
2 添加 so 库文件
- 在
android目录下,有一个armeabi文件夹。 - 将整个
armeabi文件夹复制到你的 Android 项目的app/src/main/jniLibs目录下。jniLibs目录不存在,请手动创建。- 注意: 如果你的 App 支持
arm64-v8a等其他架构,需要将 SDK 压缩包中对应架构的so文件也一并复制到jniLibs目录下对应的子文件夹中。
- 注意: 如果你的 App 支持
3 配置 AndroidManifest.xml
在 app/src/main/AndroidManifest.xml 文件中,需要添加权限和 AK。

-
添加权限: 在
<manifest>标签内添加以下权限:<!-- 访问网络权限,用于地图 SDK 验证、路况信息和 POI 搜索等 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 获取基于网络的位置信息,用于地图 SDK 定位和导航 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 读取设备上的外部存储,用于写入缓存地图数据 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 读取设备上的外部存储,用于读取缓存地图数据 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 获取精确位置权限,用于地图 SDK 定位 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 获取大致位置权限,用于地图 SDK 定位 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Android 6.0 以上系统需要动态申请权限 --> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
-
添加 AK 和 Service: 在
<application>标签内添加meta-data来配置你的AK。<application ...> <!-- 请将 YOUR_API_KEY 替换为你自己申请的 AK --> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="YOUR_API_KEY" /> <!-- 百度地图定位服务 --> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" /> ... 你的 Activity ... </application>- 重要: 将
YOUR_API_KEY替换为你在第一步获取的真实AK。
- 重要: 将
4 配置 build.gradle (Module: app)
在 app/build.gradle 文件的 android 块中,添加 sourceSets 配置,确保 so 库能被正确打包。
android {
...
defaultConfig {
...
// 添加这一行
sourceSets {
main {
jniLibs.srcDirs = ['jniLibs']
}
}
}
...
}
在布局文件中添加地图控件
打开 app/src/main/res/layout/activity_main.xml 文件,添加 MapView 控件。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- 百度地图控件 -->
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
在 Activity 中初始化地图
这是最关键的一步,你需要让 Activity 实现 BDAbstractLocationListener 接口来接收定位结果。
1 添加网络权限和定位服务声明 (Android 8.0+)
为了兼容 Android 8.0 (Oreo) 及以上系统,需要在 AndroidManifest.xml 中声明 INTERNET 权限和定位服务,并确保在 Application 标签内声明。
2 编写 MainActivity 代码
package com.example.baidumapdemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Toast;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
public class MainActivity extends AppCompatActivity {
private MapView mMapView;
private BaiduMap mBaiduMap;
private LocationClient mLocationClient;
private boolean isFirstLocate = true; // 是否是第一次定位
// 需要动态申请的权限
private static final int PERMISSIONS_REQUEST_CODE = 1;
private static final String[] PERMISSIONS = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化地图
mMapView = findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
// 开启定位图层
mBaiduMap.setMyLocationEnabled(true);
// 初始化定位客户端
mLocationClient = new LocationClient(getApplicationContext());
mLocationClient.registerLocationListener(new MyLocationListener());
// 检查并请求权限
checkAndRequestPermissions();
}
private void checkAndRequestPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// 如果没有权限,则请求权限
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSIONS_REQUEST_CODE);
} else {
// 如果有权限,开始定位
startLocation();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户授权,开始定位
startLocation();
} else {
// 用户拒绝授权
Toast.makeText(this, "定位权限被拒绝,无法显示当前位置", Toast.LENGTH_SHORT).show();
}
}
}
private void startLocation() {
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); // 打开GPS
option.setCoorType("bd09ll"); // 设置坐标类型为百度经纬度
option.setScanSpan(1000); // 设置定位间隔,单位毫秒
mLocationClient.setLocOption(option);
mLocationClient.start();
}
// 定位结果回调
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// 获取定位结果
if (location == null || mMapView == null) {
return;
}
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(location.getDirection())
.latitude(location.getLatitude())
.longitude(location.getLongitude())
.build();
mBaiduMap.setMyLocationData(locData);
// 如果是第一次定位,则将地图中心移动到当前位置
if (isFirstLocate) {
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(ll, 16.0f);
mBaiduMap.animateMapStatus(msu);
isFirstLocate = false;
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 在 activity 销毁时,销毁定位客户端
mLocationClient.stop();
mLocationClient.unRegisterLocationListener(new MyLocationListener());
// 在 activity 销毁时,关闭地图
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
// 在 activity 恢复时,重新绘制地图
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
// 在 activity 暂停时,暂停地图绘制
mMapView.onPause();
}
}
代码解释:
BDAbstractLocationListener: 定位信息监听接口,需要实现onReceiveLocation方法来处理定位结果。LocationClient: 定位服务的客户端,需要配置选项并启动。LocationClientOption: 定位选项,可以设置定位模式、坐标类型、频率等。setCoorType("bd09ll"): 非常重要! 必须设置为百度自己的坐标系bd09ll,否则定位点会偏移。
BaiduMap.setMyLocationEnabled(true): 开启定位图层,否则无法显示蓝点。MyLocationData: 构建定位数据对象,包含经纬度、方向、精度等。isFirstLocate: 一个标志位,用于判断是否是第一次定位,如果是,就将地图视角移动到当前位置,并缩放到合适的级别(如16级)。- 生命周期管理:
onCreate,onResume,onPause,onDestroy中对MapView和LocationClient进行相应的管理,这是防止内存泄漏的关键。
核心功能实现
1 实现基本地图显示
这部分在上面的 MainActivity 中已经完成,包括添加 MapView、初始化 BaiduMap、配置 AK 和权限。
2 获取并显示当前位置
同样在 MainActivity 中已经实现,核心是 LocationClient 和 BDAbstractLocationListener。
3 在地图上添加标记点
// 在 MainActivity 中添加一个方法
private void addMarker(LatLng point, String title) {
// 创建 BitmapDescriptor
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory
.fromResource(R.drawable.ic_marker); // 准备一个 marker 图标
// 创建 OverlayOptions
OverlayOptions overlayOptions = new MarkerOptions()
.position(point) // 设置 marker 位置
.icon(bitmapDescriptor) // 设置 marker 图标
.title(title); // 设置 marker 标题
// 在地图上添加 marker
mBaiduMap.addOverlay(overlayOptions);
}
// 在定位成功后,可以调用此方法添加标记
// addMarker(new LatLng(location.getLatitude(), location.getLongitude()), "我的位置");
注意: 你需要在 res/drawable 目录下放置一个名为 ic_marker.png 的图标文件。
4 绘制折线/多边形
// 在 MainActivity 中添加一个方法
private void drawPolyline() {
// 创建点集合
List<LatLng> points = new ArrayList<>();
points.add(new LatLng(39.939234, 116.357499));
points.add(new LatLng(39.919234, 116.367499));
points.add(new LatLng(39.909234, 116.377499));
// 创建 OverlayOptions
OverlayOptions overlayOptions = new PolylineOptions()
.points(points) // 设置点集合
.width(10) // 设置线宽
.color(Color.argb(255, 255, 0, 0)); // 设置颜色
// 在地图上绘制
mBaiduMap.addOverlay(overlayOptions);
}
5 路线规划 (驾车)
-
添加依赖: 在
app/build.gradle的dependencies中添加路线规划 SDK。implementation files('libs/BaiduLBS_Android.jar') // 确保 jar 包已添加 // 如果是单独的路线规划包,也需要添加 // implementation files('libs/routearch.jar') // 假设的包名BaiduLBS_Android.jar已经包含了基础路线规划功能。 -
编写路线规划代码:
import com.baidu.mapapi.search.route.BikingRouteResult; import com.baidu.mapapi.search.route.DrivingRoutePlanOption; import com.baidu.mapapi.search.route.DrivingRouteResult; import com.baidu.mapapi.search.route.DrivingRouteSearch; import com.baidu.mapapi.search.route.OnGetDrivingRouteResultListener; import com.baidu.mapapi.search.route.PlanNode; import com.baidu.mapapi.search.route.TransitRouteResult; import com.baidu.mapapi.search.route.WalkingRouteResult; // 在 MainActivity 中添加成员变量 private DrivingRouteSearch mDrivingRouteSearch; // 在 onCreate 中初始化 mDrivingRouteSearch = new DrivingRouteSearch(); mDrivingRouteSearch.setOnGetDrivingRouteResultListener(new OnGetDrivingRouteResultListener() { @Override public void onGetDrivingRouteResult(DrivingRouteResult result) { if (result == null || result.error != 0) { Toast.makeText(MainActivity.this, "规划失败", Toast.LENGTH_SHORT).show(); return; } // 获取第一条路线 DrivingRouteLine routeLine = result.getRouteLines().get(0); // 将路线绘制到地图上 mBaiduMap.addOverlay(new PolylineOptions() .points(routeLine.getEntrieRoute()) .width(10) .color(Color.argb(255, 0, 0, 255))); // 移动地图视角以显示整条路线 MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngBounds(routeLine.getEntrieRoute().get(0)); mBaiduMap.animateMapStatus(msu); } @Override public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {} @Override public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {} @Override public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {} }); // 添加一个方法来触发规划 private void planRoute() { PlanNode stNode = PlanNode.withCityNameAndPlaceName("北京", "天安门"); PlanNode enNode = PlanNode.withCityNameAndPlaceName("北京", "百度大厦"); mDrivingRouteSearch.searchDrivingRoute(new DrivingRoutePlanOption() .from(stNode) .to(enNode)); }注意: 路线规划功能需要网络连接,你可以通过点击按钮等方式调用
planRoute()方法。
完整代码示例
请将上面各个部分整合到你的 MainActivity.java 文件中,并确保布局文件、权限和 SDK 文件都已正确配置。
常见问题与注意事项
-
地图不显示(黑屏)
- 检查 AK: 确认
AndroidManifest.xml中的YOUR_API_KEY是否正确。 - 检查权限: 确认
INTERNET和ACCESS_FINE_LOCATION等权限已添加并授予。 - 检查包名: 确认申请 AK 时填写的包名与你的项目包名完全一致。
- 检查 SHA1: 确认申请 AK 时填写的 SHA1 是从你的签名文件中获取的,而不是 debug.keystore(除非你一直用 debug 模式打包)。
- 检查 AK: 确认
-
定位点偏移
- 这是最常见的问题! 确保你在
LocationClientOption中设置了setCoorType("bd09ll"),如果你的其他数据(如 GPS 坐标)是 WGS84 或 GCJ02,必须先转换为 BD09 坐标才能在百度地图上正确显示。
- 这是最常见的问题! 确保你在
-
so库加载失败- 确认
so库文件是否正确放置在app/src/main/jniLibs/目录下。 - 检查
build.gradle中的sourceSets配置是否正确。
- 确认
-
混淆打包问题
- 如果你的项目启用了 ProGuard/R8 混淆,需要在
proguard-rules.pro文件中添加以下规则,防止 SDK 被错误混淆:-keep class com.baidu.mapapi.** { *; } -keep class com.baidu.location.** { *; } -keep class com.baidu.searchbox.** { *; } -keep class com.baidu.baidulocation.** { *; }
- 如果你的项目启用了 ProGuard/R8 混淆,需要在
-
Android 12+ 权限
- 对于 Android 12 (API 31) 及以上,
ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION被合并为ACCESS_FINE_LOCATION,但在代码中,为了兼容性,最好还是同时声明这两个权限,在运行时,只需请求ACCESS_FINE_LOCATION即可。
- 对于 Android 12 (API 31) 及以上,
进阶学习
完成基础功能后,你可以探索更多高级功能:
- 地图覆盖物: 更多类型的覆盖物,如圆形、信息窗口等。
- 地图交互: 监听地图点击事件、缩放事件等。
- POI 搜索: 搜索周边的餐厅、酒店、加油站等。
- 地理编码与逆地理编码: 将地址转换为坐标,或将坐标转换为地址。
- 离线地图: 下载并使用离线地图包。
- 自定义地图样式: 通过 JSON 文件自定义地图的显示样式。
希望这份详细的教程能帮助你成功地在 Android 应用中集成百度地图!祝你开发顺利!
