java– 静止时使用TYPE_ROTATION_VECTOR实现当前的基数方向方法?

java– 静止时使用TYPE_ROTATION_VECTOR实现当前的基数方向方法?,第1张

概述似乎有许多旧的例子表明在Android设备上获得当前的主要方向,但Google提供的官方解决方案似乎并未出现在他们的文档中.不推荐使用的最旧参考Sensor.TYPE_ORIENTATION,最新的参考文献提到了Sensor.TYPE_ACCELEROMETER和Sensor.TYPE_MAGNETIC_FIELD(我试过但收效甚微 - 准确性根据设备方向快

似乎有许多旧的例子表明在Android设备上获得当前的主要方向,但Google提供的官方解决方案似乎并未出现在他们的文档中.

不推荐使用的最旧参考Sensor.TYPE_ORIENTATION,最新的参考文献提到了Sensor.TYPE_ACCELEROMETER和Sensor.TYPE_MAGNETIC_FIELD(我试过但收效甚微 – 准确性根据设备方向快速变化).我一直在尝试使用像this.这样的两个实现,我甚至见过一些TYPE.GraviTY.

most recent seem to suggest TYPE_ROTATION_VECTOR显然是一个融合传感器(reference),但示例实现似乎并不容易获得.

我需要使用这些位置/运动传感器,而不是GPS,因为在需要进行此测量时,用户不会移动.无论手机是平的还是垂直的(如果你正在拍照),也需要测量稳定

在我们以某种方式拉出度数测量之后,转换到基本方向似乎很容易.(https://stackoverflow.com/a/25349774/1238737)

以前的方案

> How to get Direction in Android (Such as North,West)
> https://stackoverflow.com/a/11068878/1238737最佳答案我之前正在研究开源地图项目,如OsmAnd,MapsWithMe和MapBox.我认为这些项目是地图和导航领域中最好的AndroID开源.我检查了他们的代码,发现当手机垂直然后围绕垂直轴(y)旋转时,显示罗盘的MapBox方法是稳定的.如果旋转矢量传感器可用,它使用TYPE_ROTATION_VECTOR.否则,它使用TYPE_ORIENTATION传感器或TYPE_ACCELEROMETER和TYPE_MAGNETIC_FIELD的组合.在使用TYPE_ACCELEROMETER和TYPE_MAGNETIC_FIELD的情况下,可以通过低通滤波器减少结果的振荡,以实现更平滑的值.

这是MapBox的指南针引擎及其用法.
.

LocationComponentCompassEngine.java:

import androID.harDWare.Sensor;import androID.harDWare.SensorEvent;import androID.harDWare.SensorEventListener;import androID.harDWare.SensorManager;import androID.os.SystemClock;import androID.support.annotation.NonNull;import androID.support.annotation.Nullable;import androID.vIEw.Surface;import androID.vIEw.WindowManager;import timber.log.Timber;import java.util.ArrayList;import java.util.List;/** * This manager class handles compass events such as starting the tracking of device bearing,or * when a new compass update occurs. */public class LocationComponentCompassEngine implements SensorEventListener {    // The rate sensor events will be delivered at. As the AndroID documentation states,this is only    // a hint to the system and the events might actually be received faster or slower then this    // specifIEd rate. Since the minimum AndroID API levels about 9,we are able to set this value    // ourselves rather than using one of the provIDed constants which deliver updates too quickly for    // our use case. The default is set to 100ms    private static final int SENSOR_DELAY_MICROS = 100 * 1000;    // Filtering coefficIEnt 0 < Alpha < 1    private static final float Alpha = 0.45f;    // Controls the compass update rate in milliseconds    private static final int COMPASS_UPDATE_RATE_MS = 500;    private final WindowManager windowManager;    private final SensorManager sensorManager;    private final List

CompassListener.java:

/** * Callbacks related to the compass */public interface CompassListener {    /**     * Callback's invoked when a new compass update occurs. You can Listen into the compass updates     * using {@link LocationComponent#addCompassListener(CompassListener)} and implementing these     * callbacks. Note that this interface is also used internally to to update the UI chevron/arrow.     *     * @param userheading the new compass heading     */    voID onCompassChanged(float userheading);    /**     * This gets invoked when the compass accuracy status changes from one value to another. It     * provIDes an integer value which is IDentical to the {@code SensorManager} class constants:     * 

MainActivity.java:

import androID.content.Context;import androID.harDWare.SensorManager;import androID.os.Bundle;import androID.support.annotation.Nullable;import androID.support.v7.app.AppCompatActivity;import androID.vIEw.WindowManager;import androID.Widget.TextVIEw;import java.util.Locale;public class MainActivity extends AppCompatActivity {    private LocationComponentCompassEngine compassEngine;    private float prevIoUsCompassbearing = -1f;    @OverrIDe    protected voID onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.activity_main);        final TextVIEw textVIEw = findVIEwByID(R.ID.textVIEw);        CompassListener compassListener = new CompassListener() {            @OverrIDe            public voID onCompassChanged(float targetCompassbearing) {                if (prevIoUsCompassbearing < 0) {                    prevIoUsCompassbearing = targetCompassbearing;                }                float normalizedbearing =                        LocationComponentCompassEngine.shortestRotation(targetCompassbearing,prevIoUsCompassbearing);                prevIoUsCompassbearing = targetCompassbearing;                String status = "NO_CONTACT";                switch (compassEngine.getLastAccuracySensorStatus()) {                    case SensorManager.SENSOR_STATUS_NO_CONTACT:                        status = "NO_CONTACT";                        break;                    case SensorManager.SENSOR_STATUS_UNREliABLE:                        status = "UNREliABLE";                        break;                    case SensorManager.SENSOR_STATUS_ACCURACY_LOW:                        status = "ACCURACY_LOW";                        break;                    case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:                        status = "ACCURACY_MEDIUM";                        break;                    case SensorManager.SENSOR_STATUS_ACCURACY_HIGH:                        status = "ACCURACY_HIGH";                        break;                }                textVIEw.setText(String.format(Locale.getDefault(),"Compassbearing: %f\nAccuracySensorStatus: %s",normalizedbearing,status));            }            @OverrIDe            public voID onCompassAccuracyChange(int compassstatus) {            }        };        WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);        SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);        compassEngine = new LocationComponentCompassEngine(windowManager,sensorManager);        compassEngine.addCompassListener(compassListener);        compassEngine.onStart();    }    @OverrIDe    protected voID onDestroy() {        super.onDestroy();        compassEngine.onStop();    }}
总结

以上是内存溢出为你收集整理的java – 静止时使用TYPE_ROTATION_VECTOR实现当前的基数方向方法?全部内容,希望文章能够帮你解决java – 静止时使用TYPE_ROTATION_VECTOR实现当前的基数方向方法?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1139610.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)