小工具知识网

当前位置: 首页 > 行业知识 > android Studio调用百度地图API(实现实时定位+地图模式切换功能)

行业知识

android Studio调用百度地图API(实现实时定位+地图模式切换功能)

2026-11-04 20:44:26 来源:互联网转载

开头:本次研究此功能是为了完成APP项目中的导航功能和mark标记功能,考虑到GFW问题和baidu map调用速度更快的原因,所以开始了我的百度地图调用初探。

开发学习工具:GPT-4、CSDN

学习链接:Android 程序开发——百度地图的使用(三) 地图定位(定位+跟随+距离测量+地图自适应缩放)_地图根据两点距离 显示地图缩放-CSDN博客android百度地图(实现定位)。六_locationmode.normal-CSDN博客(特别感谢两位大佬的无私分享,让我一步步思路变得越来越清晰,对原理的掌握越来越透彻)

步骤:

一、参考官方开发文档Android地图SDK | 百度地图API SDK

强烈建议开发调用baidumap api的时候先去仔细看看官方的开发文档,会很清晰!

二、具体过程

1、引入SDK那些基础的就不写了,大家可以首选参考官方文档

2、具体写一下代码逻辑

①//在使用SDK各组件之前初始化context信息,传入ApplicationContext

②初始化定位

③请求定位权限

④获取地图控件引用

⑤注册LocationListener监听器

⑥启动定位功能

⑦开启地图定位图层

⑧通过LocationClientOption设置LocationClient相关参数

设置locationClientOption

以下是具体代码

AppLication
import com.baidu.mapapi.CoordType;import com.baidu.mapapi.SDKInitializer;public class AppLication extends Application {    @Override    public void onCreate() {        super.onCreate();        // 在使用 SDK 各组间之前初始化 context 信息,传入 ApplicationContext        // 默认本地个性化地图初始化方法        SDKInitializer.initialize(getApplicationContext());        // 自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.        // 包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。        SDKInitializer.setCoordType(CoordType.BD09LL);    }}
MapNavigationActivity.class
import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import android.Manifest;import android.content.pm.PackageManager;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageButton;import android.widget.Toast;import com.baidu.location.BDAbstractLocationListener;import com.baidu.location.BDLocation;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.BaiduMap;import com.baidu.mapapi.map.BitmapDescriptorFactory;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MapView;import com.baidu.mapapi.map.MarkerOptions;import com.baidu.mapapi.map.MyLocationData;import com.baidu.mapapi.model.LatLng;import com.example.outdoor.R;public class MapNavigationActivity extends AppCompatActivity {    private MapView mMapView = null;    private BaiduMap mBaiduMap;    private LocationClient mLocationClient;    private double user_latitude;    private double user_longitude;    private boolean isSatellite = false; // 用于跟踪当前地图模式    private static final int REQUEST_LOCATION_PERMISSION = 1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        SDKInitializer.setAgreePrivacy(getApplicationContext(), true);        //在使用SDK各组件之前初始化context信息,传入ApplicationContext        SDKInitializer.initialize(getApplicationContext());        //自4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.        //包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。        SDKInitializer.setCoordType(CoordType.BD09LL);        //注意该方法要再setContentView方法之前实现        setContentView(R.layout.activity_map_navigation);        LocationClient.setAgreePrivacy(true);        try {            mLocationClient = new LocationClient(this);        } catch (Exception e) {            Toast.makeText(this, "定位初始化失败: " + e.getMessage(), Toast.LENGTH_LONG).show();            Log.e("LocationClientInit", "定位初始化失败", e); // 添加这行日志        }        // 请求定位权限        requestLocationPermission();        //获取地图控件引用        mMapView = (MapView) findViewById(R.id.bmapView);        mBaiduMap = mMapView.getMap();        if (mBaiduMap != null) {            //注册LocationListener监听器            MyLocationListener myLocationListener = new MyLocationListener(mBaiduMap);            mLocationClient.registerLocationListener(myLocationListener);            //启动定位功能            mBaiduMap.setMyLocationEnabled(true);        }        // 设置默认的地图模式为普通地图        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);        //开启地图定位图层        mLocationClient.start();        //通过LocationClientOption设置LocationClient相关参数        LocationClientOption option = new LocationClientOption();        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备        option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系        option.setScanSpan(1000);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要        option.setLocationNotify(true);//可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到        option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀***这个进程,默认不杀***        option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集        option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤GPS仿真结果,默认需要        option.setNeedDeviceDirect(true);        //设置locationClientOption        mLocationClient.setLocOption(option);        // 设置按钮的点击事件        ImageButton  btnSwitchMap = (ImageButton ) findViewById(R.id.btn_switch_map);        btnSwitchMap.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // 切换地图模式                if (isSatellite) {                    // 当前是卫星地图,切换到普通地图                    mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);                } else {                    // 当前是普通地图,切换到卫星地图                    mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);                }                isSatellite = !isSatellite; // 更新当前地图模式的跟踪状态            }        });        ImageButton  btn_locate = (ImageButton) findViewById(R.id.btn_locate);        btn_locate.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                // 请求定位权限,如果已授权则启动定位客户端                requestLocationPermission();                requestLocationAndUpdateMap();            }        });    }    @Override    protected void onStart() {        super.onStart();        if (mLocationClient != null && !mLocationClient.isStarted()) {            mLocationClient.start();        }    }    @Override    protected void onResume() {        super.onResume();        //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理        mMapView.onResume();    }    @Override    protected void onPause() {        super.onPause();        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理        mMapView.onPause();    }    @Override    protected void onDestroy() {        mLocationClient.stop();        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理        mMapView.onDestroy();        mBaiduMap.setMyLocationEnabled(false);        mMapView = null;        super.onDestroy();    }    private void requestLocationAndUpdateMap() {        if (mLocationClient != null && mLocationClient.isStarted()) {            mLocationClient.requestLocation(); // 请求定位            Toast.makeText(this, "正在请求定位...", Toast.LENGTH_SHORT).show();        } else {            // 需要时,启动定位客户端            mLocationClient.start();            Toast.makeText(this, "启动定位客户端...", Toast.LENGTH_SHORT).show();        }    }    // 定位到用户当前位置    private void showUserLocation() {        LatLng latLng = new LatLng(user_latitude, user_longitude);        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);        mBaiduMap.animateMapStatus(msu);        Toast.makeText(this, "正在定位到设备当前位置...", Toast.LENGTH_SHORT).show();    }    private void requestLocationPermission() {        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);        } else {            // 权限已经被授予            startLocationClient();        }    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        if (requestCode == REQUEST_LOCATION_PERMISSION) {            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {                // 权限被授予                startLocationClient();            } else {                // 权限被拒绝                Toast.makeText(this, "定位权限被拒绝", Toast.LENGTH_SHORT).show();            }        }    }    private void startLocationClient() {        if (mLocationClient != null && !mLocationClient.isStarted()) {            mLocationClient.start();            Toast.makeText(this, "定位客户端已启动", Toast.LENGTH_SHORT).show();        }    }    public class MyLocationListener extends BDAbstractLocationListener {        private BaiduMap mBaiduMap; // BaiduMap实例        private boolean isFirstLoc = true; // 标记是否首次定位        private boolean isRequest = false; // 标记是否按需求定位        // 构造函数,传入BaiduMap实例        public MyLocationListener(BaiduMap baiduMap) {            this.mBaiduMap = baiduMap;        }        @Override        public void onReceiveLocation(BDLocation location) {            //mapView 销毁后不在处理新接收的位置            if (location == null || mBaiduMap == null){                Toast.makeText(MapNavigationActivity.this, "定位结果为空或BaiduMap未初始化", Toast.LENGTH_SHORT).show();                return;  // 如果定位结果为空或者BaiduMap实例未初始化,则不处理            }            // 显示定位信息            String locInfo = "Lat: " + location.getLatitude() + ", Lng: " + location.getLongitude();            Toast.makeText(MapNavigationActivity.this, locInfo, Toast.LENGTH_LONG).show();            MyLocationData locData = new MyLocationData.Builder()                    .accuracy(location.getRadius()) // 设置定位精度                    .direction(location.getDirection()) // 设置方向信息,此处设置开发者获取到的方向信息,顺时针0-360                    .latitude(location.getLatitude()) // 设置纬度                    .longitude(location.getLongitude()) // 设置经度                    .build();            mBaiduMap.setMyLocationData(locData);            if (isFirstLoc || isRequest) {                // 将地图中心移动到定位点                LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());                MapStatusUpdate update = MapStatusUpdateFactory.newLatLngZoom(ll, 18f); // 18f是缩放级别                mBaiduMap.animateMapStatus(update);                // 显示弹出覆盖物,这里以显示一个Marker为例                if (isFirstLoc) {                    MarkerOptions markerOptions = new MarkerOptions().position(ll)                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_xingcheng)); // icon_geo是你的标记图标                    mBaiduMap.addOverlay(markerOptions);                }                isFirstLoc = false;                isRequest = false;            }            // 更新用户位置            MapNavigationActivity.this.user_latitude = location.getLatitude();            MapNavigationActivity.this.user_longitude = location.getLongitude();            // 调用showUserLocation方法,定位到用户当前位置            MapNavigationActivity.this.showUserLocation();        }    }}

最后效果:

要注意:android studio调用百度地图api只能在真机上进行测试,模拟器不行哦,建议是先在编译器中查看Logcat,出现以下报错再去真机测试,会省力不少

2024-02-19 23:30:21.901 23280-23358 AndroidRuntime          com.example.outdoor                  E  FATAL EXCEPTION: GLThread 650

                                                                                                    Process: com.example.outdoor, PID: 23280

                                                                                                    java.lang.IllegalArgumentException: eglChooseConfig failed

                                                                                                        at com.baidu.platform.comapi.map.f$a.a(GLRenderControl.java:839)

                                                                                                        at com.baidu.platform.comapi.map.f$h.a(GLRenderControl.java:1014)

                                                                                                        at com.baidu.platform.comapi.map.f$i.k(GLRenderControl.java:1431)

                                                                                                        at com.baidu.platform.comapi.map.f$i.run(GLRenderControl.java:1271)

开发是一件苦尽甘来的事情,如果有帮到您,感谢点赞关注呐~

上一篇:【python技能树】python简介

下一篇:放映机服务器怎么收费?