{"id":211704,"date":"2024-03-09T20:10:31","date_gmt":"2024-03-09T20:10:31","guid":{"rendered":"https:\/\/michigandigitalnews.com\/index.php\/2024\/03\/09\/consistent-device-orientation-for-all\/"},"modified":"2025-06-25T17:20:56","modified_gmt":"2025-06-25T17:20:56","slug":"consistent-device-orientation-for-all","status":"publish","type":"post","link":"https:\/\/michigandigitalnews.com\/index.php\/2024\/03\/09\/consistent-device-orientation-for-all\/","title":{"rendered":"Consistent device orientation for all"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<meta content=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEivlmOIXvZ0LXZ7s7UJSt2VDp1CTLp0uzvJE-6x3OFM7RD56fK17QakAcXpCpPYwf7uGvps_vafNFohnc4Lo0XQXmzNY7XpiEyhltnMz6mR3cgg8EjZmSBv-rYiPaw3AxwbpCY5SsVD7_G1kzo6ZxZVq6dtszshGnp1Bd1X-EmWDg5Wy1NYPrKd7p7tN6I\/s1600\/social-Introducing-the-Fused-Orientation-Provider-API--Consistent-device-orientation-for-all-.png\" name=\"twitter:image\"\/><br \/>\n<img decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEivlmOIXvZ0LXZ7s7UJSt2VDp1CTLp0uzvJE-6x3OFM7RD56fK17QakAcXpCpPYwf7uGvps_vafNFohnc4Lo0XQXmzNY7XpiEyhltnMz6mR3cgg8EjZmSBv-rYiPaw3AxwbpCY5SsVD7_G1kzo6ZxZVq6dtszshGnp1Bd1X-EmWDg5Wy1NYPrKd7p7tN6I\/s1600\/social-Introducing-the-Fused-Orientation-Provider-API--Consistent-device-orientation-for-all-.png\" style=\"display: none;\"\/><\/p>\n<p><em>Posted by Geoffrey Boullanger \u2013 Senior Software Engineer, Shandor Dektor \u2013 Sensors Algorithms Engineer, Martin Frassl and Benjamin Joseph \u2013 Technical Leads and Managers<\/em><\/p>\n<p><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhp8dFtNlqMsgK3ffDx0qB8ZflPr8veMx-8cyMDDW7rk453Sn7KLo-j63a5s22_hgKl5K9lnhFnxq1YVMYg7TFaLy7-WsobcOlAvoy3mtFpn34H-GuurME8i_A-HS4gNgjzcb1BeGcMyBO0UXeoG5m8ahfWjwv07qSoWsG3sdt-Fw2mXbv7ZHGXtWuzNEc\/s1600\/header-Introducing-the-Fused-Orientation-Provider-API--Consistent-device-orientation-for-all-.png\"><img decoding=\"async\" border=\"0\" data-original-height=\"800\" data-original-width=\"100%\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhp8dFtNlqMsgK3ffDx0qB8ZflPr8veMx-8cyMDDW7rk453Sn7KLo-j63a5s22_hgKl5K9lnhFnxq1YVMYg7TFaLy7-WsobcOlAvoy3mtFpn34H-GuurME8i_A-HS4gNgjzcb1BeGcMyBO0UXeoG5m8ahfWjwv07qSoWsG3sdt-Fw2mXbv7ZHGXtWuzNEc\/s1600\/header-Introducing-the-Fused-Orientation-Provider-API--Consistent-device-orientation-for-all-.png\"\/><\/a><\/p>\n<p>Device orientation, or attitude, is used as an input signal for many use cases: virtual or augmented reality, gesture detection, or compass and navigation \u2013 any time the app needs the orientation of a device in relation to its surroundings. We\u2019ve heard from developers that orientation is challenging to get right, with frequent user complaints when orientation is incorrect. A maps app should show the correct direction to walk towards when a user is navigating to an exciting restaurant in a foreign city!<\/p>\n<p>The Fused Orientation Provider (FOP) is a new API in Google Play services that provides quality and consistent device orientation by fusing signals from accelerometer, gyroscope and magnetometer.<\/p>\n<p>Although currently the Android Rotation Vector already provides device orientation (and will continue to do so),  the new FOP provides more consistent behavior and high performance across devices. We designed the FOP API to be similar to the Rotation Vector to make the transition as easy as possible for developers.<\/p>\n<p>In particular, the Fused Orientation Provider<\/p>\n<ul style=\"text-align: left;\">\n<ul>\n<li>Provides a unified implementation across devices: an API in Google Play services means that there is no implementation variance across different manufacturers. Algorithm updates can be rolled out quickly and independent of Android platform updates;<\/li>\n<\/ul>\n<\/ul>\n<ul style=\"text-align: left;\">\n<ul>\n<li>Directly incorporates local magnetic declination, if available;<\/li>\n<\/ul>\n<\/ul>\n<ul style=\"text-align: left;\">\n<ul>\n<li>Compensates for lower quality sensors and OEM implementations (e.g., gyro bias, sensor timing).<\/li>\n<\/ul>\n<\/ul>\n<p>In certain cases, the FOP returns values piped through from the AOSP Rotation Vector, adapted to incorporate magnetic declination.<\/p>\n<h3>How to use the FOP API<\/h3>\n<p>Device orientation updates can be requested by creating and sending a DeviceOrientationRequest object, which defines some specifics of the request like the update period.<\/p>\n<p>The FOP then outputs a stream of the device\u2019s orientation estimates as quaternions. The orientation is referenced to <b>geographic<\/b> north. In cases where the local magnetic declination is not known (e.g., location is not available), the orientation will be relative to <b>magnetic<\/b> north.<\/p>\n<p>In addition, the FOP provides the device\u2019s heading and accuracy, which are derived from the orientation estimate. This is the same heading that is shown in Google Maps, which uses the FOP as well. We recently added changes to better cope with magnetic disturbances, to improve the reliability of the cone for Google Maps and FOP clients.<\/p>\n<p>The update rate can be set by requesting a specific update period. The FOP does not guarantee a minimum or maximum update rate. For example, the update rate can be faster than requested if another app has a faster parallel request, or it can be slower as requested if the device doesn\u2019t support the high rate.<\/p>\n<p>For full specification of the API, please consult the API documentation:<\/p>\n<h3>Example usage (Kotlin)<\/h3>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"font-family: courier;\"><span style=\"color: green; font-weight: bold;\">package<\/span> <span style=\"color: blue; font-weight: bold;\">...<\/span>\n\nimport android.content.Context\nimport com.google.android.gms.location.DeviceOrientation\nimport com.google.android.gms.location.DeviceOrientationListener\nimport com.google.android.gms.location.DeviceOrientationRequest\nimport com.google.android.gms.location.FusedOrientationProviderClient\nimport com.google.android.gms.location.LocationServices\nimport com.google.common.flogger.FluentLogger\nimport java.util.concurrent.Executors\n\n<span style=\"color: green; font-weight: bold;\">class<\/span> <span style=\"color: blue;\">Example<\/span>(context: Context) {\n  <span style=\"color: green; font-weight: bold;\">private<\/span> <span style=\"color: green; font-weight: bold;\">val<\/span> logger: FluentLogger = FluentLogger.forEnclosingClass()\n\n  <span style=\"color: #408080; font-style: italic;\">\/\/ Get the FOP API client<\/span>\n  <span style=\"color: green; font-weight: bold;\">private<\/span> <span style=\"color: green; font-weight: bold;\">val<\/span> fusedOrientationProviderClient: FusedOrientationProviderClient =\n    LocationServices.getFusedOrientationProviderClient(context)\n\n  <span style=\"color: #408080; font-style: italic;\">\/\/ Create an FOP listener<\/span>\n  <span style=\"color: green; font-weight: bold;\">private<\/span> <span style=\"color: green; font-weight: bold;\">val<\/span> listener: DeviceOrientationListener =\n    DeviceOrientationListener { orientation: DeviceOrientation -&gt;\n      <span style=\"color: #408080; font-style: italic;\">\/\/ Use the orientation object returned by the FOP, e.g.<\/span>\n      logger.atFinest().log(<span style=\"color: #ba2121;\">\"Device Orientation: %s deg\"<\/span>, orientation.headingDegrees)\n    }\n\n  <span style=\"color: green; font-weight: bold;\">fun<\/span> <span style=\"color: blue;\">start<\/span>() {\n    <span style=\"color: #408080; font-style: italic;\">\/\/ Create an FOP request<\/span>\n    <span style=\"color: green; font-weight: bold;\">val<\/span> request =\n      DeviceOrientationRequest.Builder(DeviceOrientationRequest.OUTPUT_PERIOD_DEFAULT).build()\n\n    <span style=\"color: #408080; font-style: italic;\">\/\/ Create (or re-use) an Executor or Looper, e.g.<\/span>\n    <span style=\"color: green; font-weight: bold;\">val<\/span> executor = Executors.newSingleThreadExecutor()\n\n    <span style=\"color: #408080; font-style: italic;\">\/\/ Register the request and listener<\/span>\n    fusedOrientationProviderClient\n      .requestOrientationUpdates(request, executor, listener)\n      .addOnSuccessListener { logger.atInfo().log(<span style=\"color: #ba2121;\">\"FOP: Registration Success\"<\/span>) }\n      .addOnFailureListener { e: Exception? -&gt;\n        logger.atSevere().withCause(e).log(<span style=\"color: #ba2121;\">\"FOP: Registration Failure\"<\/span>)\n      }\n  }\n\n  <span style=\"color: green; font-weight: bold;\">fun<\/span> <span style=\"color: blue;\">stop<\/span>() {\n    <span style=\"color: #408080; font-style: italic;\">\/\/ Unregister the listener<\/span>\n    fusedOrientationProviderClient.removeOrientationUpdates(listener)\n  }\n}<\/span>\n<\/pre>\n<\/div>\n<h3>Technical background<\/h3>\n<p>The Android ecosystem has a wide variety of system implementations for sensors. Devices should meet the criteria in the <a href=\"https:\/\/source.android.com\/docs\/compatibility\/cdd\" target=\"_blank\" rel=\"noopener\">Android compatibility definition document (CDD)<\/a> and must have an accelerometer, gyroscope, and magnetometer available to use the fused orientation provider. It is preferable that the device vendor implements the high fidelity sensor portion of the CDD.<\/p>\n<p>Even though Android devices adhere to the Android CDD, recommended sensor specifications are not tight enough to fully prevent orientation inaccuracies. Examples of this include magnetometer interference from internal sources, and delayed, inaccurate or nonuniform sensor sampling. Furthermore, the environment around the device usually includes materials that distort the geomagnetic field, and user behavior can vary widely. To deal with this, the FOP performs a number of tasks in order to provide a robust and accurate orientation:<\/p>\n<ol\/>\n<ul>\n<li>Synchronize sensors running on different clocks and delays;<\/li>\n<li>Compensate for the hard iron offset (magnetometer bias);<\/li>\n<li>Fuse accelerometer, gyroscope, and magnetometer measurements to determine the orientation of the device in the world;<\/li>\n<li>Compensate for gyro drift (gyro bias) while moving;<\/li>\n<li>Produce a realistic estimate of the compass heading accuracy.<\/li>\n<\/ul>\n<p>We have validated our algorithms on comprehensive test data to provide a high quality result on a wide variety of devices.<\/p>\n<h3>Availability and limitations<\/h3>\n<p>The Fused Orientation Provider is available on all devices running Google Play services on Android 5 (Lollipop) and above. Developers need to add the dependency <span style=\"color: #0d904f; font-family: Courier;\">play-services-location:21.2.0<\/span> (or above) to access the new API.<\/p>\n<p><b>Permissions<\/b><\/p>\n<p>No permissions are required to use the FOP API. The output rate is limited to 200Hz on devices running API level 31 (Android S) or higher, unless the <span style=\"color: #0d904f; font-family: Courier;\">android.permissions.HIGH_SAMPLING_RATE_SENSORS<\/span> permission was added to your Manifest.xml.<\/p>\n<p><b>Power consideration<\/b><\/p>\n<p>Always request the longest update period (lowest frequency) that is sufficient for your use case. While more frequent FOP updates can be required for high precision tasks (for example Augmented Reality), it comes with a power cost. If you do not know which update period to use, we recommend starting with <span style=\"color: #0d904f; font-family: Courier;\">DeviceOrientationRequest::OUTPUT_PERIOD_DEFAULT<\/span> as it fits most client needs.<\/p>\n<p><b>Foreground behavior<\/b><\/p>\n<p>FOP updates are only available to apps running in the foreground.<\/p>\n<p><\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">Copyright <span style=\"color: #666666;\">2023<\/span> Google LLC<span style=\"color: #666666;\">.<\/span>\nSPDX<span style=\"color: #666666;\">-<\/span>License<span style=\"color: #666666;\">-<\/span>Identifier<span style=\"color: #666666;\">:<\/span> Apache<span style=\"color: #666666;\">-2.0<\/span>\n<\/pre>\n<\/div>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"http:\/\/android-developers.googleblog.com\/2024\/03\/introducing-fused-orientation-provider-api.html\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Posted by Geoffrey Boullanger \u2013 Senior Software Engineer, Shandor Dektor \u2013 Sensors Algorithms Engineer, Martin Frassl and Benjamin Joseph \u2013 Technical Leads and Managers<\/p>\n","protected":false},"author":1,"featured_media":211705,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[146],"tags":[],"_links":{"self":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/211704"}],"collection":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/comments?post=211704"}],"version-history":[{"count":1,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/211704\/revisions"}],"predecessor-version":[{"id":339130,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/211704\/revisions\/339130"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media\/211705"}],"wp:attachment":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media?parent=211704"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/categories?post=211704"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/tags?post=211704"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}