安卓开发(3)百度地图SDK的使用和地图显示功能的实现

安卓开发(0)前言&目录

概述和几点建议

这部分就是一直报错、调试,多搭配使用try-catchlog捕捉错误和排查问题,适应百度地图SDK的使用。

虽然我这里用的是百度地图,但还是要说一句:更推荐使用高德地图。经过这段时间的实际使用,感觉百度地图的整体体验很差,无论是文档质量还是依赖管理,都远不如高德地图完善。

鉴权失败”不用管,出现鉴权失败,可能是确实没有配置好API_KEY,但其实即使配置好了,log中也还是会出现这个错误。

最后一定要记得:必须提前显式同意隐私协议,否则功能一直无法正常使用。

第一步:申请百度地图 API Key

登录百度地图开放平台

首先,访问 百度地图开放平台 并使用百度账号登录。

创建应用

  1. 登录后进入 控制台

  2. 点击「创建应用」按钮,为你的应用起一个有意义的名字,这有助于后续管理。

  3. 选择应用类型为安卓端

  4. 配置包名SHA1。你可以从项目的 build.gradle 文件中找到包名,并通过命令行工具获取 SHA1 指纹(开发版和发布版可以使用相同的 SHA1)。

  5. 启用所有需要的服务并保存配置。

注意:创建成功后,请记录下生成的API Key (AK)SHA1包名,以便在代码中使用。

第二步:配置 Android 项目

添加依赖(Gradle)

现在使用比较方便的SDK都会提供一个远程依赖链接,然后写入build.gradle(.kts)然后由Gragle自动去获取。例如:

dependencies {
    implementation 'com.somecompany:sdk:latest.version'
}

我不知道百度地图有没有提供,一直都没有找到。我到现在也无法通过简单的 implementation 'com.baidu:xxx' 来引入。(如果有谁知道,感谢分享一下。)

官网上提供的它的集成方式是“手动导入”:

  1. 去官网下载 .aar 文件(或 .jar + so 库);

  2. 手动复制到项目的 app/libs/ 目录;

  3. build.gradle 中配置本地依赖:

所以这里下载.aar手动导入和配置,下载时选择尽量多的功能。

手动导入步骤:
  1. 下载 .aar 文件:从百度地图官网下载最新版本的 .aar 文件。(如果下载的是.jar会更麻烦一点,需要在app/src/main下面创建一个jniLibs文件夹,把类似x86_64x86这四个文件夹复制进去。)

  2. 放置文件:将下载的 BaiduLBS_Android.aar 放入项目的 app/libs 目录下。如果下载的是 .jar 文件,则需在 app/src/main 下创建 jniLibs 文件夹并将相关库文件放入其中。

  3. 配置 build.gradle

添加依赖项:

dependencies {
  implementation(name: 'BaiduLBS_Android', ext: 'aar')
}

权限配置

添加权限

AndroidManifest.xml 中添加以下权限(这是一部分,调试过程中会加上更多权限):

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
配置 API Key

<application> 标签内添加以下元数据配置:

<meta-data
    android:name="com.baidu.lbsapi.API_KEY"
    android:value="你的API_KEY" />

初始化 SDK

MainActivityonCreate 方法中,确保在 super.onCreate() 后、setContentView() 前调用 SDKInitializer.initialize(getApplicationContext())。这样可以确保地图引擎在界面加载之前已经初始化完成。

或者是新建一个MyApplication类来执行SDK的初始化,因为我在多个页面使用了同一个地图,为了避免重复初始化的问题。MyApplication是一个什么东西下面会说。

示例代码如下:

@Override
private void initBaiduMapSDK() {
        try {
            // 在使用SDK各组件之前初始化context信息,传入ApplicationContext
            // 设置同意隐私合规政策
            SDKInitializer.setAgreePrivacy(getApplicationContext(), true);
            
            // 初始化定位SDK
            SDKInitializer.initialize(getApplicationContext());
            
            // 设置坐标类型为百度经纬度坐标
            SDKInitializer.setCoordType(CoordType.BD09LL);
            
            Log.d(TAG, "百度地图SDK初始化成功");
        } catch (Exception e) {
            Log.e(TAG, "百度地图SDK初始化失败", e);
        }

一定要注意,初始化第一件事是同意隐私协议!!否则接下来的操作都无法进行。SDKInitializer.setAgreePrivacy(getApplicationContext(), true);

点击“Sync Now”同步项目以确保所有更改生效。

神奇的MyApplication.java

public class MyApplication extends Application它继承了Android系统提供的Application基类,从而获得了应用全局上下文和生命周期管理能力。

这个东西在打开软件的时候,比MainActivity.java执行还早,所以可以专门用来初始化。

Android应用默认情况下并没有MyApplication类,是项目开发者为了实现特定功能(如地图SDK初始化)而专门创建的。

💣💣注意MyApplication.java一定要保持最简洁的状态,只执行单一的职责!

进入软件后的执行顺序:

  1. 系统创建MyApplication实例

  2. 系统调用MyApplication.onCreate()方法 (执行地图SDK初始化)

  3. 系统创建MainActivity实例

  4. 系统调用MainActivity.onCreate()方法

第三步:在首页中显示地图

关键组件与文件

  1. MainActivity.java - 应用主入口,负责管理导航和界面交互

  2. MapFragment.java - 地图功能实现的核心Fragment

  3. 布局文件 - 主要包括activity_main.xml和fragment_map.xml

地图界面显示实现步骤

MainActivity中导航组件配置

这个其实在上一篇构建基本框架的时候已经完成了。

MainActivity通过Navigation组件实现底部导航栏和Fragment切换,关键代码如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // 使用 ViewBinding 加载布局文件,避免 findViewById
    binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());

    // 获取底部导航视图组件
    BottomNavigationView navView = findViewById(R.id.nav_view);

    // 定义哪些 Fragment 页面应被视为“顶层目的地”(Top-level Destinations)
    AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
            R.id.navigation_map,   // 地图页面的 Fragment ID
            R.id.navigation_ar)    // AR 页面的 Fragment ID
            .build();

    // 获取 NavController,它是 Navigation 组件的核心控制器
    NavController navController = Navigation.findNavController(
            this, 
            R.id.nav_host_fragment_activity_main  // 对应布局中的 <navHostFragment> ID
    );

    // 设置 ActionBar(标题栏)的行为:
    // - 当用户处于顶层页面时,不显示返回箭头;
    // - 进入子页面时才显示返回按钮。
    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);

    // 将 BottomNavigationView 与 NavController 关联
    // 实现点击底部标签自动切换 Fragment
    NavigationUI.setupWithNavController(binding.navView, navController);

    // 其他初始化操作...
}
MapFragment初始化与地图视图创建

MapFragment在onCreateView方法中初始化地图视图和相关功能:

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    MapViewModel mapViewModel = new ViewModelProvider(this).get(MapViewModel.class);

    binding = FragmentMapBinding.inflate(inflater, container, false);
    View root = binding.getRoot();

    // 初始化百度地图
    initBaiduMap();

    // 初始化地图点击监听
    setupMapClick();

    // 加载初始楼层地图数据(f1.json)
    loadJsonMapData("f1.json");

    return root;
}
百度地图初始化配置

在initBaiduMap方法中,进行了百度地图的核心配置:

private void initBaiduMap() {
        try {
            Log.d(TAG, "开始初始化百度地图");
            
            // 检查MapView是否正确获取
            mMapView = binding.bmapView;
            if (mMapView != null) {
                Log.d(TAG, "MapView实例获取成功");
                
                // 检查MapView是否可见
                if (mMapView.getVisibility() == View.VISIBLE) {
                    Log.d(TAG, "MapView可见");
                } else {
                    Log.d(TAG, "MapView不可见,尝试设置为可见");
                    mMapView.setVisibility(View.VISIBLE);
                }
                
                // 获取BaiduMap对象
                mBaiduMap = mMapView.getMap();
                if (mBaiduMap != null) {
                    Log.d(TAG, "BaiduMap实例获取成功");
                    
                    // 设置地图初始状态
                    mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
                    Log.d(TAG, "地图类型设置为普通地图");


                    // 确保所有手势都启用(否则后面点击地点可能不会有反应)
                    mBaiduMap.getUiSettings().setAllGesturesEnabled(true);

                    // 启用缩放手势
                    mBaiduMap.getUiSettings().setZoomGesturesEnabled(true);
                    Log.d(TAG, "启用缩放手势");
                    
                    // 设置是否允许俯视
                    mBaiduMap.getUiSettings().setOverlookingGesturesEnabled(false);
                    Log.d(TAG, "禁用俯视手势");
                    
                    // 设置是否允许旋转
                    mBaiduMap.getUiSettings().setRotateGesturesEnabled(false);
                    Log.d(TAG, "百度地图旋转手势已禁用");
                    
                    
                    // 如果有已知位置,立即移动到该位置
                    if (lastKnownLocation != null) {
                        moveMapToLocation(lastKnownLocation);
                    }
                    
                    Log.d(TAG, "百度地图初始化成功");
                } else {
                    Log.e(TAG, "获取BaiduMap实例失败");
                }
            } else {
                Log.e(TAG, "获取MapView实例失败");
            }
        } catch (Exception e) {
            Log.e(TAG, "初始化百度地图时发生异常", e);
        }
    }

获取 MapView 实例:通过 ViewBinding 获取布局中的 MapView,检查是否为空,并确保其可见,避免地图不显示。MapView是百度地图的提供的一个控件,用来显示地图,但是注意这个时候百度地图SDK必须已经初始化。

获取 BaiduMap 控制器:调用 getMap() 获取核心地图对象,若返回 null 则初始化失败,需检查布局或 SDK 初始化状态。

设置地图类型:将地图设为普通模式:MAP_TYPE_NORMAL,确保加载标准二维地图。

启用必要手势:开启所有手势,并特别启用缩放,保证用户可以双指操作地图。

禁用旋转与俯视:关闭旋转和俯视手势,防止误操作,保持界面稳定。

参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值