android开发百度地图api实现定位图标随手机方向转动

news/2025/2/19 17:01:54/

该功能的实现依赖于手机中的传感器元件如陀螺仪、加速度计等,具体开发详见android的官方开发文档:

传感器概览  |  Android 开发者  |  Android Developersicon-default.png?t=N7T8https://developer.android.com/guide/topics/sensors/sensors_overview?hl=zh-cn要自定义一个传感器监听器类实现该功能,套路与实现定位功能类似,但是网上关于定位图标随手机方向转动的文章并不多,且大多割裂了与定位功能之间的联系。

首先自定义一个传感器监听器类:

    //自定义传感器监听器类public  class MyOrientationListener implements SensorEventListener{private SensorManager sensorManager;//注册传感器监听器方法public void registerSensorListener() {sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),SensorManager.SENSOR_DELAY_UI);}// 关闭传感器监听器的方法public void unregisterSensorListener() {sensorManager.unregisterListener(this);}// 监听传感器变化事件,当传感器数值发生变化时,该方法被调用public void onSensorChanged(SensorEvent sensorEvent) {// 读取传感器数值中的 x 轴方向的值double x = sensorEvent.values[SensorManager.DATA_X];// 判断当前 x 轴方向的值与上一次记录的值之间的差值是否超过了 1.0,如果超过了 1.0,更新当前方向为新的 x 轴方向的值。if (Math.abs(x - lastX) > 1.0) {mCurrentDirection = (float) x;// 构造定位图层数据MyLocationData  myLocationData = new MyLocationData.Builder().accuracy(mCurrentAccracy)// 此处设置开发者获取到的方向信息,顺时针0-360.direction(mCurrentDirection).latitude(mCurrentLantitude).longitude(mCurrentLongtitude).build();// 设置定位图层数据baiduMap.setMyLocationData(myLocationData);}// 将当前 x 轴方向的值记录为上一次的值,用于下一次比较lastX = x;}public void onAccuracyChanged(Sensor sensor, int accuracy) {// 传感器精度变化时的回调方法}}

SensorEventListener是一个接口,它用于监听传感器事件的回调。当与传感器相关的事件发生时,系统会调用 SensorEventListener 的方法来通知你。

在这个类中要自己实现注册监听器和注销监听器的方法,这两种方法的实现官方文档中都有,可以直接用:

定位图标指示方向 | 百度地图API SDK (baidu.com)icon-default.png?t=N7T8https://lbsyun.baidu.com/index.php?title=%E5%AE%9A%E4%BD%8D%E5%9B%BE%E6%A0%87%E6%8C%87%E7%A4%BA%E6%96%B9%E5%90%91关键是onSensorChanged这个方法,是该功能实现的核心,在该方法中定义了处理传感器信息的逻辑,如何确定方向。

在构造定位图层数据时,经纬度和精确度都可以从定位功能的监听器中直接取:

定位功能实现详见android开发调用百度地图api实现加载地图和定位-CSDN博客

  //通过继承抽象类BDAbstractListener并重写其onReceieveLocation方法来获取定位数据,并将其传给MapView。public class MyLocationListener extends BDAbstractLocationListener  {@Overridepublic void onReceiveLocation(BDLocation location) {int locType = location.getLocType();Log.d("定位结果错误码", String.valueOf(locType));//mapView 销毁后不再处理新接收的位置if (location == null || mMapView == null) {             //判断 location 和 mMapView 是否为空来确保在地图视图销毁后不再处理新接收的位置return;}mCurrentLongtitude = location.getLongitude();mCurrentLantitude = location.getLatitude();mCurrentAccracy = location.getRadius();MyLocationData locData = new MyLocationData.Builder()       //通过 Builder 模式,设置位置的精度、方向、纬度和经度等属性。.accuracy(location.getRadius())// 从传感器拿到方向信息.direction(mCurrentDirection).latitude(location.getLatitude()).longitude(location.getLongitude()).build();baiduMap.setMyLocationData(locData);                //将新的位置信息更新到地图上,以显示当前设备的位置

 其中mCurrentLongtitude、mCurrentLantitude、mCurrentAccracy这三个变量在MainActivity的onCreate方法之前定义,在定位监听器中获取经纬度和精确度值然后在传感器监听器中使用。

但是关键在方向的获取:

博主最开始编写完该功能之后,发现一个现象:图标箭头可以随着手机的转动而转动,但是每当转动一个角度之后都会弹回最开始的方向,并不能最终指向正确方向,经过研究,博主发现是因为传感器获取到的方向信息并没有持续传递给定位功能,导致每次手机停止转动之后,定位监听器类拿到的方向信息都不是手机的最新方向。

所以当每次传感器类中计算完方向之后都要把方向传递给定位功能:

 //通过 Builder 模式,设置位置的精度、方向、纬度和经度等属性。       
MyLocationData locData = new MyLocationData.Builder()      .accuracy(location.getRadius())// 从传感器拿到方向信息.direction(mCurrentDirection).latitude(location.getLatitude()).longitude(location.getLongitude()).build();

最后还要打开显示方向信息:

这部分代码放在onCreate()中就可以

 // 创建 MyLocationConfiguration 对象并设置相关属性,enableDirection=true则允许显示方向MyLocationConfiguration config = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, // 定位模式为跟随态                true, // 显示方向信息null,0xAAec2d7a, // 填充颜色0xAA2376b7 // 描边颜色);baiduMap.setMyLocationConfiguration(config);

注册监听器和注销监听器的方法不要忘记调用:

    @Overrideprotected void onResume() {super.onResume();//开始传感器监听myOrientationListener.registerSensorListener();//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理mMapView.onResume();}@Overrideprotected void onPause() {super.onPause();//终止传感器监听myOrientationListener.unregisterSensorListener();//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理mMapView.onPause();}


http://www.ppmy.cn/news/1289784.html

相关文章

力扣42. 接雨水

双指针法 思路: 将数组前后设置为 left、right 指针,相互靠近;在逼近的过程中记录两端最大的值 leftMax、rightMax,作为容器的左右边界;更新指针规则: 如果数组左边的值比右边的小,则更新 left…

vue实现画笔回放,canvas转视频播放功能

示例图&#xff1a; 一、vue2版本 <template><div class"canvas-video"><canvasref"myCanvasByVideo"class"myCanvas"id"myCanvasByVideo":width"width":height"height"></canvas><d…

postgresql拆分文本

unnest(string_to_array(‘文本’,‘,’)) 示例&#xff1a; with orders as (select unnest(string_to_array(${参数1},‘,’))) select * from analy.test1 where id in (select * from orders) with orders as (select unnest(string_to_array(${参数1},,))) select * from…

thinkcmf 文件包含 x1.6.0-x2.2.3 已亲自复现

thinkcmf 文件包含 x1.6.0-x2.2.3 CVE-2019-16278 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 ThinkCMF是一款基于PHPMYSQL开发的中文内容管理框架&#xff0c;底层采用ThinkPHP3.2.3构建。ThinkCMF提出灵活的应用机制&a…

深度学习-数据基本使用

数据使用 文章目录 数据使用一、数据的获取1、图片爬虫工具2、视频爬虫工具3、复杂的爬虫工具(flickr)4、按照用户的ID来爬取图片5、对一些特定的网站进行爬&#xff08;摄影网站&#xff09;(图虫、500px&#xff0c;花瓣网等等)6、爬虫合集 二、数据整理1、数据检查与归一化2…

面试算法79:所有子集

题目 输入一个不含重复数字的数据集合&#xff0c;请找出它的所有子集。例如&#xff0c;数据集合[1&#xff0c;2]有4个子集&#xff0c;分别是[]、[1]、[2]和[1&#xff0c;2]。 分析 如果集合中包含n个元素&#xff0c;那么生成子集可以分为n步&#xff0c;每一步从集合中…

MySQL数据库高级SQL语句及存储过程

目录 一、高级SQL语句 &#xff08;一&#xff09;case语句 1.语法定义 2.示例 &#xff08;二&#xff09;空值(NULL) 和 无值( ) 1.区别 2.示例 &#xff08;1&#xff09;字符长度 &#xff08;2&#xff09;判断方法 ① 空值(NULL) ② 无值( ) &#xff08;3…

k8s的二进制部署和网络类型

k8s的二进制部署 master01&#xff1a;192.168.233.10 kube-apiserver kube-controller-manager kube-scheduler etcd master02&#xff1a;192.168.233.20 kube-apiserver kube-controller-manager kube-scheduler node01&#xff1a;192.168.233.30 kubelet kube-proxy etc…