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

04-27 1615阅读

开头:本次研究此功能是为了完成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

以上是onCreate中的内容,其中第一步Application需要自己创建一个,LocationListener监听器写在本activity中就可以。两个点注意一下就可以

以下是具体代码

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(实现实时定位+地图模式切换功能)

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

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

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)

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

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]