杰瑞科技汇

Android百度地图教程怎么用?

目录

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

准备工作

在开始编码之前,你必须完成以下步骤,这是使用百度地图 SDK 的前提。

Android百度地图教程怎么用?-图1
(图片来源网络,侵删)

1 注册百度开发者账号

  1. 访问 百度地图开放平台
  2. 点击右上角的“登录/注册”,使用你的百度账号登录,如果没有账号,需要先注册。

2 创建应用并获取密钥

密钥是你的应用调用百度地图服务的唯一凭证。

  1. 登录后,进入“控制台”。
  2. 在左侧菜单栏选择“应用管理” -> “我的应用”。
  3. 点击“创建应用”按钮。
  4. 填写应用信息:
    • 应用名称: 填写你的应用名称,"我的第一个百度地图App"。
    • 应用类型: 选择 Android SDK
    • 发布版 SHA1: 这是关键!你需要获取你发布版应用的签名 SHA1 值。
    • 开发版 SHA1: 同样需要,用于在手机上调试。
  5. 如何获取 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。

  6. 填写包名: 填写你 Android 项目的包名,com.example.baidumapdemo
  7. 创建应用: 点击“提交”按钮,创建成功后,你会看到一个应用列表,其中包含你刚刚创建的应用。
  8. 获取 AK (Access Key): 在你的应用列表中,找到对应的应用,复制 API Key,这个 AK 就是你在代码中需要使用的密钥。

3 下载百度地图 SDK

  1. 回到 百度地图开放平台,点击“开发文档” -> “Android SDK” -> “下载”。
  2. 选择你需要的 SDK 服务,我们至少需要:
    • 基础地图 SDK
    • 定位 SDK
    • 搜索 SDK
    • 路线规划 SDK
  3. 下载后,你会得到一个压缩包,里面包含了 jar 包、so 库文件、以及 demo 示例。

Android Studio 项目配置

将下载好的 SDK 集成到你的 Android Studio 项目中。

1 添加 SDK Jar 包

  1. 解压下载的 SDK 压缩包。
  2. 找到 android 目录下的 BaiduLBS_Android.jar 文件。
  3. 将这个 jar 文件复制到你的 Android 项目的 app/libs 目录下。
  4. 在 Android Studio 中,右键点击 libs 目录 -> Add As Library...,确保勾选并添加到你的 app 模块中。

2 添加 so 库文件

  1. android 目录下,有一个 armeabi 文件夹。
  2. 将整个 armeabi 文件夹复制到你的 Android 项目的 app/src/main/jniLibs 目录下。jniLibs 目录不存在,请手动创建。
    • 注意: 如果你的 App 支持 arm64-v8a 等其他架构,需要将 SDK 压缩包中对应架构的 so 文件也一并复制到 jniLibs 目录下对应的子文件夹中。

3 配置 AndroidManifest.xml

app/src/main/AndroidManifest.xml 文件中,需要添加权限和 AK

Android百度地图教程怎么用?-图2
(图片来源网络,侵删)
  1. 添加权限:<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" />
  2. 添加 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 控件。

Android百度地图教程怎么用?-图3
(图片来源网络,侵删)
<?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();
    }
}

代码解释:

  1. BDAbstractLocationListener: 定位信息监听接口,需要实现 onReceiveLocation 方法来处理定位结果。
  2. LocationClient: 定位服务的客户端,需要配置选项并启动。
  3. LocationClientOption: 定位选项,可以设置定位模式、坐标类型、频率等。
    • setCoorType("bd09ll"): 非常重要! 必须设置为百度自己的坐标系 bd09ll,否则定位点会偏移。
  4. BaiduMap.setMyLocationEnabled(true): 开启定位图层,否则无法显示蓝点。
  5. MyLocationData: 构建定位数据对象,包含经纬度、方向、精度等。
  6. isFirstLocate: 一个标志位,用于判断是否是第一次定位,如果是,就将地图视角移动到当前位置,并缩放到合适的级别(如16级)。
  7. 生命周期管理: onCreate, onResume, onPause, onDestroy 中对 MapViewLocationClient 进行相应的管理,这是防止内存泄漏的关键。

核心功能实现

1 实现基本地图显示

这部分在上面的 MainActivity 中已经完成,包括添加 MapView、初始化 BaiduMap、配置 AK 和权限。

2 获取并显示当前位置

同样在 MainActivity 中已经实现,核心是 LocationClientBDAbstractLocationListener

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 路线规划 (驾车)

  1. 添加依赖: 在 app/build.gradledependencies 中添加路线规划 SDK。

    implementation files('libs/BaiduLBS_Android.jar') // 确保 jar 包已添加
    // 如果是单独的路线规划包,也需要添加
    // implementation files('libs/routearch.jar') // 假设的包名

    BaiduLBS_Android.jar 已经包含了基础路线规划功能。

  2. 编写路线规划代码:

    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 文件都已正确配置。


常见问题与注意事项

  1. 地图不显示(黑屏)

    • 检查 AK: 确认 AndroidManifest.xml 中的 YOUR_API_KEY 是否正确。
    • 检查权限: 确认 INTERNETACCESS_FINE_LOCATION 等权限已添加并授予。
    • 检查包名: 确认申请 AK 时填写的包名与你的项目包名完全一致。
    • 检查 SHA1: 确认申请 AK 时填写的 SHA1 是从你的签名文件中获取的,而不是 debug.keystore(除非你一直用 debug 模式打包)。
  2. 定位点偏移

    • 这是最常见的问题! 确保你在 LocationClientOption 中设置了 setCoorType("bd09ll"),如果你的其他数据(如 GPS 坐标)是 WGS84 或 GCJ02,必须先转换为 BD09 坐标才能在百度地图上正确显示。
  3. so 库加载失败

    • 确认 so 库文件是否正确放置在 app/src/main/jniLibs/ 目录下。
    • 检查 build.gradle 中的 sourceSets 配置是否正确。
  4. 混淆打包问题

    • 如果你的项目启用了 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.** { *; }
  5. Android 12+ 权限

    • 对于 Android 12 (API 31) 及以上,ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION 被合并为 ACCESS_FINE_LOCATION,但在代码中,为了兼容性,最好还是同时声明这两个权限,在运行时,只需请求 ACCESS_FINE_LOCATION 即可。

进阶学习

完成基础功能后,你可以探索更多高级功能:

  • 地图覆盖物: 更多类型的覆盖物,如圆形、信息窗口等。
  • 地图交互: 监听地图点击事件、缩放事件等。
  • POI 搜索: 搜索周边的餐厅、酒店、加油站等。
  • 地理编码与逆地理编码: 将地址转换为坐标,或将坐标转换为地址。
  • 离线地图: 下载并使用离线地图包。
  • 自定义地图样式: 通过 JSON 文件自定义地图的显示样式。

希望这份详细的教程能帮助你成功地在 Android 应用中集成百度地图!祝你开发顺利!

分享:
扫描分享到社交APP
上一篇
下一篇