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

  • 22
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
安卓调用百度地图代码示例: 1. 在 AndroidManifest.xml 文件中添以下权限: ```xml <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/> ``` 2. 在 build.gradle 文件中添以下依赖: ``` implementation 'com.baidu.android:map-sdk:5.3.0' ``` 3. 在布局文件中添 MapView 控件: ```xml <com.baidu.mapapi.map.MapView android:id="@+id/bmapView" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 4. 在 Activity 中添以下代码: ```java public class MainActivity extends AppCompatActivity { private MapView mMapView = null; private BaiduMap mBaiduMap = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化地图 mMapView = findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); // 显示地图 LatLng latLng = new LatLng(39.915071, 116.403907); MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latLng); mBaiduMap.setMapStatus(mapStatusUpdate); // 添标记 MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("北京市"); markerOptions.draggable(false); Marker marker = (Marker) mBaiduMap.addOverlay(markerOptions); } @Override protected void onDestroy() { super.onDestroy(); mMapView.onDestroy(); } @Override protected void onResume() { super.onResume(); mMapView.onResume(); } @Override protected void onPause() { super.onPause(); mMapView.onPause(); } } ``` 苹果调用百度地图代码示例: 1. 在 Xcode 项目中创建桥接文件(Bridging-Header.h),并添以下内容: ```objective-c #import <BaiduMapAPI_Base/BMKBaseComponent.h> #import <BaiduMapAPI_Map/BMKMapComponent.h> #import <BaiduMapAPI_Search/BMKSearchComponent.h> ``` 2. 在 Podfile 文件中添以下依赖: ``` pod 'BaiduMapKit' ``` 3. 在 Swift 代码中添以下代码: ```swift import UIKit import BaiduMapKit class ViewController: UIViewController, BMKMapViewDelegate { var mapView: BMKMapView! override func viewDidLoad() { super.viewDidLoad() mapView = BMKMapView(frame: view.bounds) mapView.delegate = self view.addSubview(mapView) let coordinate = CLLocationCoordinate2D(latitude: 39.915071, longitude: 116.403907) let annotation = BMKPointAnnotation() annotation.coordinate = coordinate annotation.title = "北京市" mapView.addAnnotation(annotation) let region = BMKCoordinateRegion(center: coordinate, span: BMKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)) mapView.setRegion(region, animated: true) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) mapView.viewWillAppear() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) mapView.viewWillDisappear() } func mapViewDidFinishLoading(_ mapView: BMKMapView!) { print("地图完成") } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_坐看云起时_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值