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

目录

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

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(),实现地图生命周期管理
    }
}

<think>好的,用户的问题是如何将百度地图SDK获取的定位信息显示到Android应用的TextView控件中。我需要根据提供的引用资料我的知识来解答这个问题。 首先,用户提到他们已经集成了百度地图的SDK,并且想要将定位结果显示在自定义的TextView上。根据引用[3][4],百度地图定位服务需要在AndroidManifest中配置Service组件,并且可能需要处理密钥权限的问题。 接下来,我需要回忆百度地图SDK的使用流程。通常,定位功能需要初始化定位客户端,设置定位参数,然后注册定位监听器。当定位成功后,监听器会返回位置信息,这时候就可以从中提取经纬度、地址等数据,并更新TextView的显示。 用户提供的引用中,引用[2]提到如何获取TextView的高度,这可能动态调整布局有关,但当前问题主要是显示定位信息,所以可能不需要这部分。不过,需要注意在UI线程中更新TextView的内容,避免在子线程中直接操作UI导致崩溃。 步骤可能包括: 1. 配置AndroidManifest.xml,添加定位服务权限。 2. 初始化定位客户端,设置定位参数。 3. 实现定位监听接口,在回调中获取定位数据。 4. 将定位数据转换为字符串,设置到TextView上。 需要注意的是,定位成功后的回调可能不在主线程,所以需要使用runOnUiThread或Handler来更新UI。另外,确保权限已经申请,否则定位可能失败。 检查提供的引用[3][4],引用[3]提到了在Application中声明Service组件,引用[4]提到了生成密钥路径,这可能SHA1密钥有关,确保百度地图SDK的配置正确。用户可能需要检查AK(API Key)是否正确,否则定位服务无法使用。 最后,示例代码可能需要包括定位监听器的实现,以及如何在回调中处理数据并更新TextView。同时,提醒用户处理定位失败的情况,提供错误日志输出。</think>要将百度地图SDK的定位信息显示在TextView控件中,需通过定位监听接口获取坐标数据后更新UI组件,具体步骤如下: ### 一、配置基础环境 1. 在`AndroidManifest.xml`中添加定位权限Service声明 ```xml <!-- 定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"/> ``` (参考引用[3]的Service组件配置) ### 二、初始化定位服务 ```java public class LocationActivity extends AppCompatActivity { private TextView tvLocation; private LocationClient mLocationClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvLocation = findViewById(R.id.tv_location); // 初始化定位客户端 mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.registerLocationListener(new MyLocationListener()); // 设置定位参数 LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); // 打开GPS option.setCoorType("bd09ll"); // 坐标类型 option.setScanSpan(5000); // 定位间隔 mLocationClient.setLocOption(option); } } ``` ### 三、实现定位监听器 ```java public class MyLocationListener extends BDAbstractLocationListener { @Override public void onReceiveLocation(BDLocation location) { // 获取定位结果 double latitude = location.getLatitude(); double longitude = location.getLongitude(); String address = location.getAddrStr(); // 更新UI runOnUiThread(() -> { String locationText = String.format(Locale.CHINA, "纬度:%.4f\n经度:%.4f\n地址:%s", latitude, longitude, address); tvLocation.setText(locationText); }); } } ``` ### 四、启动定位服务 ```java @Override protected void onStart() { super.onStart(); // 检查权限 if (checkSelfPermission(ACCESS_FINE_LOCATION) == PERMISSION_GRANTED) { mLocationClient.start(); } else { requestPermissions(new String[]{ACCESS_FINE_LOCATION}, 1); } } @Override protected void onStop() { super.onStop(); mLocationClient.stop(); } ``` ### 关键说明: 1. 定位结果回调在子线程执行,必须通过`runOnUiThread`更新TextView[^2] 2. `BDLocation`对象包含详细定位数据: - `getLatitude()`:获取纬度 - `getLongitude()`:获取经度 - `getAddrStr()`:获取结构化地址 3. 需处理定位失败情况: ```java public void onReceiveLocation(BDLocation location) { if (location.getLocType() == BDLocation.TypeGpsLocation) { // GPS定位结果 } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { // 网络定位结果 } else { Log.e("定位失败", "错误码:" + location.getLocType()); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_坐看云起时_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值