我可以使用 Javascript 获取 iOS 和 Android 的指南针方向吗?

Posted

技术标签:

【中文标题】我可以使用 Javascript 获取 iOS 和 Android 的指南针方向吗?【英文标题】:Can I use Javascript to get the compass heading for iOS and Android? 【发布时间】:2013-04-09 12:50:29 【问题描述】:

我能否以跨平台方式使用 javascriptiosandroid(使用 Chrome)中获取指南针方向,而不使用 PhoneGap 之类的东西?我知道 iOS 有 DeviceOrientationEvent,但我在 Android 版 Chrome 上找不到任何等价物。

【问题讨论】:

有一个Web Compass API。我不知道它的浏览器支持,但您可以尝试在全局范围内访问getCurrentOrientation 并查看它是否存在。您可能还想尝试使用 webkit 前缀。祝你好运! 【参考方案1】:

作为入门者,您应该查看 this previous related *** answer 并熟悉 Web 应用程序中的一般 practical considerations for using DeviceOrientation Events。

我在my previous related *** answer 中提供的简单解决方案仅适用于实现absolute 设备方向事件的浏览器(即设备方向alpha 属性为compass 导向的浏览器)。这意味着那里提供的解决方案目前仅适用于 Android 浏览器,不适用于基于 iOS 的浏览器或任何其他不提供基于 absolute 的设备方向事件数据的浏览器。

今天,要在 Android 和 iOS 浏览器中可靠地获取当前指南针方向,您需要处理提供额外 webkitCompassHeading 属性的 absolute 和非 absolute 实现,并确保考虑任何当前屏幕方向作为其中的一部分进行更改。 AFAIK 目前唯一这样做的库是 Full Tilt JS(免责声明:我是这个库的作者)。

以下代码将在 iOS 和 Android 浏览器中为您提供相同的正确指南针方向,同时考虑到设备方向实现的差异并应用任何必要的运行时屏幕方向转换:

<!-- Include the Full Tilt JS library from https://github.com/richtr/Full-Tilt-JS -->
<script src="fulltilt-min.js"></script>

<script>

  // Obtain a new *world-oriented* Full Tilt JS DeviceOrientation Promise
  var promise = FULLTILT.getDeviceOrientation( 'type': 'world' );

  // Wait for Promise result
  promise.then(function(deviceOrientation)  // Device Orientation Events are supported

    // Register a callback to run every time a new 
    // deviceorientation event is fired by the browser.
    deviceOrientation.listen(function() 

      // Get the current *screen-adjusted* device orientation angles
      var currentOrientation = deviceOrientation.getScreenAdjustedEuler();

      // Calculate the current compass heading that the user is 'looking at' (in degrees)
      var compassHeading = 360 - currentOrientation.alpha;

      // Do something with `compassHeading` here...

    );

  ).catch(function(errorMessage)  // Device Orientation Events are not supported

    console.log(errorMessage);

    // Implement some fallback controls here...

  );

</script>

这是一个demo,它演示了这种技术来获取用户所面对的罗盘方向。它应该适用于 iOS 和 Android 浏览器。

该演示中的代码实现如上所示,可以在Github上查看./scripts/compass.js:L268-L272。

【讨论】:

你好 Richt,我已经测试了你的库,运行良好,但我认为它并没有给我真正的北方,对吧? 这些例子都没有在 android 上给出北方。这完全是个笑话。 @richt 获得设备方向后,我将如何使用它来获取指南针航向(指向地理点 B 的方向)?我可以从 2 个地理点(A 点和 B 点)成功计算方位(度数)。 这个图书馆有非商业许可。 自 2 月以来,Chrome 上的一个问题正在等待 PR 集成(可能解释了以前的一些 cmets):Issue github.com/adtile/Full-Tilt/issues/22 PR github.com/adtile/Full-Tilt/pull/25 :-/【参考方案2】:

是的,你可以!不幸的是,alpha 不适用于 iPhone/iPad。在 Mobile Safari 中,alpha 基于首次请求设备方向时设备指向的方向。包含的 webkit 为您提供指南针方向。要使其适用于所有其他浏览器(都支持 alphacompassheading),您可以使用以下 Javascript 代码:

if (window.DeviceOrientationEvent) 
  // Listen for the deviceorientation event and handle the raw data
  window.addEventListener('deviceorientation', function(eventData) 
    var compassdir;

    if(event.webkitCompassHeading) 
      // Apple works only with this, alpha doesn't work
      compassdir = event.webkitCompassHeading;  
    
    else compassdir = event.alpha;
  );

Android 也支持 Webkit,所以也会使用 event.webkitCompassHeading,不过没关系。

顺便说一句:iPhone 和 iPad 也不支持“oncompassneedscalibration”。

【讨论】:

event.alpha 不足以获得指南针方向,alpha 只是设备在其自身轴上的 z 旋转(请参阅w3c.github.io/deviceorientation/…)。不过,可以将 alpha、beta 和 gamma 转换为指南针航向;请参阅下面@ri​​cht 的答案。 @davidjb:您的回答可能会在没有任何解释的情况下使读者感到困惑,并且richt 示例也与 alpha 通道有关。这是一个视觉示例,显示 alpha 通道与持有者视图的水平方向有关:dev.opera.com/articles/w3c-device-orientation-api 您可能想说的:如果仅使用 alpha 通道作为指南针方向,您必须水平握住手机并处于纵向模式正确使用。否则手机可能会失去方向而无法显示正确的航向。【参考方案3】:

相信你可以使用位置对象的“heading”字段,来自navigator.geolocation,请看这里:

https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation

我没有别的办法。

希望对你有帮助, A.

【讨论】:

-1。地理位置不会为您提供 Compass 数据。这不是一个真正的答案。 heading 属性表示行进方向,而不是指南针;并且不适合在室内使用。

以上是关于我可以使用 Javascript 获取 iOS 和 Android 的指南针方向吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 共享扩展中使用动态 Javascript

如何使用 Vanilla JavaScript/Ajax 获取地理位置 - 国家和城市

iOS - 通过 JavaScript 获取我在 UIWebView 中单击的图像的 URL

ios的app无法捕捉js异常信息

ios的Phonegap插件...javascript部分

swift 笔记:iOS与JavaScript的交互(二):JavaScriptCore:通过下标方式对JavaScript方法进行获取和调用: