似乎有许多旧的例子表明在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实现当前的基数方向方法?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)