android开发调用百度地图api实现加载地图和定位

news2025/1/23 17:39:48

目录

一.踩的一些坑以及解决方法

1.权限声明不要少

2.地图初始化

3.定位问题

(1)监听器注册

(2)定位监听器类MyLocationListener的实现

(3)定位功能的调用

4.android studio连接真机调试问题 

二.MainActivity的逻辑代码以及运行结果


官方文档地址:

Android地图SDK | 百度地图API SDK (baidu.com)icon-default.png?t=N7T8https://lbsyun.baidu.com/faq/api?title=androidsdk

一.踩的一些坑以及解决方法

1.权限声明不要少


    <!-- 访问网络,进行地图相关业务数据请求,包括地图数据,路线规划,POI检索等 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <!-- 读取外置存储。如果开发者使用了so动态加载功能并且把so文件放在了外置存储区域,则需要申请该权限,否则不需要 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- 写外置存储。如果开发者使用了离线地图,并且数据写在外置存储区域,则需要申请该权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- 读取设备的电话状态和身份标识  -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!-- 这个权限用于进行网络定位 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!-- 这个权限用于访问GPS定位 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

2.地图初始化

 protected void onCreate(Bundle savedInstanceState) {
        //定位监视器
        super.onCreate(savedInstanceState);
        //隐私保护,必须写,不然会报错
        SDKInitializer.setAgreePrivacy(getApplicationContext(), true);

        SDKInitializer.initialize(getApplicationContext());//一定要先初始化,再加载布局

        SDKInitializer.setCoordType(CoordType.BD09LL);    //经纬坐标,使用中国国测局的。

        setContentView(R.layout.activity_main);  //加载布局

在SDK各功能组件使用之前都需要调用“SDKInitializer.initialize(getApplicationContext())”

这一段官方文档写的不是很清晰,SDKInitializer在MainActivity类的onCreate方法中实现就可以,但是顺序不要错,初始化语句一定要写在引入布局文件的语句之前,且要在初始化之前加上同意隐私协议的语句,其他文件不需要修改。

3.定位问题

首先要完成权限的声明和地图初始化,这在之前已经陈述过。

其中这两条权限用于定位:

  <!-- 这个权限用于进行网络定位 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <!-- 这个权限用于访问GPS定位 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

        定位的逻辑需要用到java多线程编程的知识,为了避免阻塞主线程或造成线程间的等待,通常会将耗时的操作放在后台线程执行 。定位通常是一个耗时的操作,涉及到与设备硬件、网络通信等交互。为了避免主线程的阻塞和界面的卡顿,可以将定位操作放在后台线程中进行,使用多线程的技术实现异步定位。这样,应用程序的主线程可以继续响应用户的操作,同时定位操作在后台线程进行。定位操作完成后,需要将定位结果传递给应用程序进行处理。

(1)监听器注册

   public LocationClient mLocationClient= null;   
    //创建一个定位监听器类对象,MyLocationListener 是一个自定义的定位监听器类,用于接收定位结果的回调。
   private MyLocationListener myListener = new MyLocationListener();       
    try {

        //实例化LocationClient 对象并传入应用程序的上下文参数
            mLocationClient = new LocationClient(getApplicationContext());

        } catch (Exception e) {
            e.printStackTrace();
        }
        //将自定义的定位监听器 myListener 注册到 LocationClient 中
        mLocationClient.registerLocationListener(myListener);

这里必须要加上try-catch异常处理机制,不然会报错。

(2)定位监听器类MyLocationListener的实现

//通过继承抽象类BDAbstractListener并重写其onReceieveLocation方法来获取定位数据,并将其传给MapView。
    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            int locType = location.getLocType();
            Log.d("定位结果错误码", String.valueOf(locType));
            //mapView 销毁后不再处理新接收的位置
            if (location == null || mMapView == null) {             //判断 location 和 mMapView 是否为空来确保在地图视图销毁后不再处理新接收的位置
                return;
            }
            MyLocationData locData = new MyLocationData.Builder()       //通过 Builder 模式,设置位置的精度、方向、纬度和经度等属性。
                    .accuracy(location.getRadius())
                    // 此处设置开发者获取到的方向信息,顺时针0-360
                    .direction(location.getDirection())
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude())
                    .build();
            baiduMap.setMyLocationData(locData);                //将新的位置信息更新到地图上,以显示当前设备的位置

            if (isFirstLocate) {
                LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());      //根据 BDLocation 对象的经纬度创建一个 LatLng 对象
                System.out.println("纬度"+location.getLatitude());
                System.out.println("经度"+location.getLongitude());
                MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);          //将地图的中心点设置为 ll 所表示的位置
                baiduMap.animateMapStatus(update);                          //动画更新中心点
                update = MapStatusUpdateFactory.zoomTo(16f);        //将地图的缩放级别设置为 16
                baiduMap.animateMapStatus(update);              //动画更新缩放级别
                isFirstLocate = false;
            }

        }
    }

其中          int locType = location.getLocType();
            Log.d("定位结果错误码", String.valueOf(locType));

这两句是打印定位错误码到logcat窗口,去官网对照查表,就可以知道是否定位成功或者发生哪些错误。

Android定位SDK | 百度地图API SDK (baidu.com)icon-default.png?t=N7T8https://lbs.baidu.com/faq/api?title=android-locsdk/guide/addition-func/error-code如果返回的是61,161就是定位成功。

(3)定位功能的调用

mLocationClient.start();  

注意语句的顺序:

监听器的注册要在定位功能的实现之前,然后启动定位(start),然后调用编写定位参数的方法。

注意:不要重复编写监听器注册的代码,可能导致定位偏移,博主在onCreate函数中实例化了一次监听器对象,调试程序时候又在编写定位参数的函数中实例化了一次监听器对象,也就是在start()的调用前后各实例化了一次,定位到了一个离博主所在位置搁一条河的小区里面,当博主整理代码时删掉了start函数后面的实例化监听器代码,再次运行之后就定位到了博主所在位置。

4.android studio连接真机调试问题 

博主所用为华为nova6手机,harmonyos4.0.0系统,连接真机时与其他手机不同。

要下载华为手机助手:

华为手机助手HiSuite官方下载 | 华为官网 (huawei.com)icon-default.png?t=N7T8https://consumer.huawei.com/cn/support/hisuite/用usb连接之后要输入手机上的密码(手机上会自动下载华为手机助手,提供密码)到电脑的华为手机助手。

要开启手机的开发者模式,方法为连续点击设置中的版本号三次,开启usb调试功能,开启ADB,具体操作教程很多,不再赘述。

连接成功后:

在logcat窗口的左上角会显示机型,然后正常run就可以了。

要注意手机的存储空间要充足,否则把软件下载手机上会失败报错 

二.MainActivity的逻辑代码以及运行结果

package com.example.mcssignaltest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;

import android.app.Application;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;


import com.baidu.location.Address;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.CoordType;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMapOptions;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {           //AppCompatActivity是 Activity 类的一个子类,提供了对旧版本 Android 平台的兼容性支持
    public LocationClient mLocationClient= null;
    private MyLocationListener myListener = new MyLocationListener();     //创建一个定位监听器类对象
    private MapView mMapView = null;        //百度自定义地图控件
    private BaiduMap baiduMap;              //地图总控制器
    private boolean isFirstLocate = true;     //是否是首次定位
    private TextView positionText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //定位监视器
        super.onCreate(savedInstanceState);
        //隐私保护,必须写,不然会报错
        SDKInitializer.setAgreePrivacy(getApplicationContext(), true);
        LocationClient.setAgreePrivacy(true);
        //注册LocationListener监听器
        try {
            mLocationClient = new LocationClient(getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }

        mLocationClient.registerLocationListener(myListener);



        SDKInitializer.initialize(getApplicationContext());//一定要先初始化,再加载布局

        SDKInitializer.setCoordType(CoordType.BD09LL);    //经纬坐标,使用中国国测局的。

        setContentView(R.layout.activity_main);  //加载布局


        //获取地图控件引用
        mMapView = (MapView) findViewById(R.id.bmapView);
        baiduMap = mMapView.getMap();

        positionText = (TextView) findViewById(R.id.position_text_view);
        List<String> permissionList = new ArrayList<>();//权限列表,记录未允许的权限

        baiduMap.setMyLocationEnabled(true);     //开启地图的定位图层


        //判断单个权限是否已经允许
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        if (!permissionList.isEmpty()) {
            String[] permissions = permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);
        } else {
            requestLocation();      //请求位置信息
        }
    }

    //定位请求方法
    private void requestLocation() {
        mLocationClient.start();       //开始定位,回调定位监听器
        initMyLocation();         //调用本地定位方法
    }


    //权限判断
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0) {
                    for (int result : grantResults) {
                        if (result != PackageManager.PERMISSION_GRANTED) {
                            Toast.makeText(this, "必须同意所有权限才能使用本程序", Toast.LENGTH_SHORT).show();
                            finish();
                            return;
                        }
                    }
                    requestLocation();
                } else {
                    Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mMapView.onPause();
    }

    //通过继承抽象类BDAbstractListener并重写其onReceieveLocation方法来获取定位数据,并将其传给MapView。
    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            int locType = location.getLocType();
            Log.d("定位结果错误码", String.valueOf(locType));
            //mapView 销毁后不再处理新接收的位置
            if (location == null || mMapView == null) {             //判断 location 和 mMapView 是否为空来确保在地图视图销毁后不再处理新接收的位置
                return;
            }
            MyLocationData locData = new MyLocationData.Builder()       //通过 Builder 模式,设置位置的精度、方向、纬度和经度等属性。
                    .accuracy(location.getRadius())
                    // 此处设置开发者获取到的方向信息,顺时针0-360
                    .direction(location.getDirection())
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude())
                    .build();
            baiduMap.setMyLocationData(locData);                //将新的位置信息更新到地图上,以显示当前设备的位置

            if (isFirstLocate) {
                LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());      //根据 BDLocation 对象的经纬度创建一个 LatLng 对象
                System.out.println("纬度"+location.getLatitude());
                System.out.println("经度"+location.getLongitude());
                MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);          //将地图的中心点设置为 ll 所表示的位置
                baiduMap.animateMapStatus(update);                          //动画更新中心点
                update = MapStatusUpdateFactory.zoomTo(16f);        //将地图的缩放级别设置为 16
                baiduMap.animateMapStatus(update);              //动画更新缩放级别
                isFirstLocate = false;
            }

        }
    }

    //通过LocationClient发起定位
    private void initMyLocation() {
        //通过LocationClientOption设置LocationClient相关参数
        LocationClientOption option = new LocationClientOption();
        //强制选择高精度定位,三种模式:Hight_Accuracy(高精度)、Battery_Saving(节电模式)、Device_Sensors(传感器模式)
        option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);
        option.setOpenGps(true); // 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(1000);           //设置位置更新间隔,1s一更新

        //设置locationClientOption
        mLocationClient.setLocOption(option);

   }

    @Override
    protected void onDestroy() {
        mLocationClient.stop();         //程序销毁时停止定位,防止消耗电量
        baiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        mMapView = null;
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1347267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言函数篇——strcat()函数

strcat()函数介绍&#xff1a; strcat()函数是C语言中用于连接两个字符串的函数。它将第二个字符串连接到第一个字符串的末尾&#xff0c;并返回第一个字符串的地址。 strcat()函数的语法&#xff1a; char *strcat(char *dest, const char *src); 其中&#xff0c;dest是目标…

pytorch03:transforms常见数据增强操作

目录 一、数据增强二、transforms--Crop裁剪2.1 transforms.CenterCrop2.2 transforms.RandomCrop2.3 RandomResizedCrop2.4 FiveCrop和TenCrop 三、transforms—Flip翻转、旋转3.1RandomHorizontalFlip和RandomVerticalFlip3.2 RandomRotation 四、transforms —图像变换4.1 t…

【JavaScript】浮点数精度问题

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

【MySQL表的增删查改】

文章目录 前言1 Create1.1 单行数据 全列插入1.2 多行数据 指定列插入1.3 插入否则更新1.4 替换 2 Retrieve2.1 SELECT 列2.1.1 全列查询2.1.2 指定列查询2.1.3 查询字段为表达式2.1.4 为查询结果指定别名2.1.5 结果去重 2.2 WHERE 条件2.2.1 英语不及格的同学及英语成绩 ( &…

vue 基础学习 一

1. vue 使用快速入门三步走 (1) 新建 HTML 页面&#xff0c;引入 Vue.js文件 1 2 3 4 5 6 7 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>Vue.js 入门示例</title> <script src"https://cdn.j…

设计模式:抽象工厂模式(讲故事易懂)

抽象工厂模式 定义&#xff1a;将有关联关系的系列产品放到一个工厂里&#xff0c;通过该工厂生产一系列产品。 设计模式有三大分类&#xff1a;创建型模式、结构型模式、行为型模式 抽象工厂模式属于创建型模式 上篇 工厂方法模式 提到工厂方法模式中每个工厂只生产一种特定…

12.29_黑马数据结构与算法笔记Java

目录 305 旅行商问题 动态规划 实现2 306 旅行商问题 动态规划 实现3 307 分治 概述 308 快速选择算法 分治 309 快速选择算法 数组第k大数 Leetcode215 310 快速选择算法 数组中位数 311 快速幂 分治 312 快速幂 Leetcode50 313 平方根整数部分 Leetcode69-1 314 平方…

从实际工作情况,介绍嵌入式(MCU)软件开发常用(通用)工具

目录 前言 1、代码阅读及编辑工具&#xff08;VSCode、Understand&#xff09; 2、代码对比工具&#xff08;Beyond Compare&#xff09; 3、代码仓库相关工具&#xff08;Git、SVN、Tortoise&#xff09; 4、文本编辑器&#xff08;Notepad&#xff09; 5、电脑文件搜索工…

arkts状态管理使用(@State、@Prop、@Link、@Provide、@Consume、@objectLink和@observed)

一、状态管理 1.在声明式UI中&#xff0c;是以状态驱动视图更新&#xff1a; ①状态&#xff08;State&#xff09;:指驱动视图更新的数据&#xff08;被装饰器标记的变量&#xff09; ②视图&#xff08;View&#xff09;:基于UI描述渲染得到用户界面 注意&#xff1a; ①…

Radar System Pro - Plug Play Solution

Radar System Pro是一款功能多样且可定制的资源,旨在通过功能齐全且易于使用的雷达系统增强您的Unity项目。无论您是在开发第一人称射击游戏、策略游戏还是太空探索模拟器,我们的雷达系统都将为您提供所需的工具,以创建引人入胜且身临其境的体验。 雷达系统是一个模块化资产…

mysql间隙锁demo分析

概述 通常用的mysql都是innodb引擎&#xff1b; 一般在update的时候用id都会认为是给行记录加锁&#xff1b; 在使用非唯一索引更新时&#xff0c;会遇到临键锁&#xff08;范围锁&#xff09;&#xff1b; 临键锁和表中的数据有关&#xff1b; mysq版本:8 隔离级别&#xf…

雨课堂作业整理

第一次作业 1.下列序列是图序列的是&#xff08; &#xff09; A.1&#xff0c;2&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;4&#xff0c;5 B.1&#xff0c;1&#xff0c;2&#xff0c;2&#xff0c;4&#xff0c;6&#xff0c;6 C.0&#xff0c;0&#xff0c;2&am…

解决基于VectorGrid的矢量瓦片Y轴偏移的问题

目录 前言 一、GeoServer的瓦片 1、GeoWebcache缓存配置 2、矢量瓦片本地缓存 3、瓦片访问 二、VectorGrid加载本地瓦片 1、加载关键代码 2、默认模式的问题 3、问题分析 4、tms参数修改 总结 前言 在前面的博文介绍中&#xff0c;在线连接如下&#xff1a;浅谈前端自定义…

AI与数字化映像:颜值开端,功能至上_光点科技

在人工智能的浪潮中&#xff0c;AI数字人的兴起正成为一个不可忽视的现象。随着ChatGPT等生成式AI算法的进步&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;的应用呈现出爆发性增长&#xff0c;不仅在技术圈引起广泛关注&#xff0c;也为元宇宙及其相关产业链带来了…

C++每日一练(8):图像相似度

题目描述 给出两幅相同大小的黑白图像&#xff08;用0-1矩阵&#xff09;表示&#xff0c;求它们的相似度。 说明&#xff1a;若两幅图像在相同位置上的像素点颜色相同&#xff0c;则称它们在该位置具有相同的像素点。两幅图像的相似度定义为相同像素点数占总像素点数的百分比。…

非科班,培训出身,怎么进大厂?

今天分享一下我是怎么进大厂的经历&#xff0c;希望能给大家带来一点点启发&#xff01; 阿七毕业于上海一所大学的管理学院&#xff0c;在读期间没写过一行 Java 代码。毕业之后二战考研失利。 回过头来看&#xff0c;也很庆幸这次考研失利&#xff0c;因为这个时候对社会一…

精品Nodejs实现的在线菜谱食谱美食学习系统的设计与实现

《[含文档PPT源码等]精品Nodejs实现的在线菜谱学习系统的设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 操作系统&#xff1a;Windows 10、Windows 7、Windows…

2023第三届中国高校大数据挑战赛B题代码

任务已完成&#xff0c;聚类效果很好&#xff08;主要在于数据的处理以及特征工程&#xff09;, 需代码si&#xff0c;yuer有限先到先得。

模型 KANO卡诺模型

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。需求分析。 1 卡诺模型的应用 1.1 餐厅需求分析故事 假设你经营一家餐厅&#xff0c;你想了解客户对你的服务质量的满意度。你可以使用卡诺模型来收集客户的反馈&#xff0c;并分析客户的…

Android Matrix画布Canvas旋转Rotate,Kotlin

Android Matrix画布Canvas旋转Rotate&#xff0c;Kotlin private fun f1() {val originBmp BitmapFactory.decodeResource(resources, R.mipmap.pic).copy(Bitmap.Config.ARGB_8888, true)val newBmp Bitmap.createBitmap(originBmp.width, originBmp.height, Bitmap.Config.…