Android development calls Baidu map api to load maps and positioning

Table of contents

1. Some pitfalls and solutions

1. Don’t be short of permission statements

2. Map initialization

3. Positioning problem

(1) Listener registration

(2) Implementation of the location listener class MyLocationListener

(3) Calling the positioning function

4. Debugging problems when connecting android studio to real device 

2. MainActivity’s logic code and running results


Official document address:

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

1. Some pitfalls and solutions

1. Don’t be short of permission statements


    <!-- 访问网络,进行地图相关业务数据请求,包括地图数据,路线规划,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. Map initialization

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

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

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

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

Before using each functional component of the SDK, you need to call "SDKInitializer.initialize(getApplicationContext())"

This section of the official document is not very clear. SDKInitializer can be implemented in the onCreate method of the MainActivity class, but the order must not be wrong. The initialization statement must be written before the statement that introduces the layout file, and the privacy agreement must be added before initialization. statement, other files do not need to be modified.

3. Positioning problem

The first step is to complete the declaration of permissions and initialization of the map, which has been stated before.

These two permissions are used for positioning:

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

        The positioning logic requires knowledge of Java multi-thread programming. In order to avoid blocking the main thread or causing waiting between threads, time-consuming operations are usually performed on background threads. Positioning is usually a time-consuming operation that involves interaction with device hardware, network communications, etc. In order to avoid blocking of the main thread and lag of the interface, the positioning operation can be performed in the background thread, and multi-threading technology can be used to implement asynchronous positioning. In this way, the application's main thread can continue to respond to user operations, while positioning operations are performed on the background thread. After the positioning operation is completed, the positioning results need to be passed to the application for processing.

(1) Listener registration

   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);

A try-catch exception handling mechanism must be added here, otherwise an error will be reported.

(2) Implementation of the location listener class 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;
            }

        }
    }

Among them          int locType = location.getLocType();
            Log.d("Location result error code", String.valueOf(locType));

These two sentences are to print the positioning error code to the logcat window. Go to the official website to check the table to know whether the positioning is successful or what errors occurred.

Android Positioning SDK | Baidu Map API SDK (baidu.com) icon-default.png?t=N7T8https://lbs.baidu.com/faq/api?title=android-locsdk/guide/addition-func/error-code If the returned value is 61, 161 is Positioning successful.

(3) Calling the positioning function

mLocationClient.start();  

Pay attention to the order of statements:

The registration of the listener must be before the implementation of the positioning function, then start the positioning (start), and then call the method of writing positioning parameters.

! Note: Do not rewrite the code for listener registration, which may cause positioning offset. The blogger instantiated the listener object once in the onCreate function, and instantiated the listener object once in the function of writing the positioning parameters when debugging the program. That is to say, it was instantiated once before and after the call to start(), and it was located in a community that is a river away from the blogger's location. When the blogger compiled the code, he deleted the instantiation listener code behind the start function, and again After running, the location of the blogger is located.

4. Debugging problems when connecting android studio to real device 

The blogger uses a Huawei nova6 mobile phone with harmonyos4.0.0 system, which is different from other mobile phones when connected to the real phone.

To download Huawei Mobile Assistant:

Huawei Mobile Assistant HiSuite official download | Huawei official website (huawei.com) icon-default.png?t=N7T8https://consumer.huawei.com/cn/support/hisuite/ After connecting via USB, you need to enter the password on your phone (Huawei Mobile Assistant will be automatically downloaded on your phone. Provide the password) to Huawei Mobile Assistant on your computer.

To turn on the developer mode of your phone, click the version number in the settings three times in succession, turn on the USB debugging function, and turn on ADB. There are many detailed operation tutorials, so I won’t go into details.

After successful connection:

The model will be displayed in the upper left corner of the logcat window, and then run normally.

Please note that the storage space of your mobile phone must be sufficient, otherwise downloading the software to your mobile phone will fail and report an error. 

2. MainActivity’s logic code and running results

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

Guess you like

Origin blog.csdn.net/qq_53162179/article/details/135316644