Introducing the Proximity API

Smartphones and mobile devices have gained a lot of importance in our life and it seems increasingly that we cannot live without them.

When used properly and with moderation they are valuable tools that can help us in achieving common tasks such as knowing the next bus, locating the nearest tube, searching for an Italian restaurant and so on.

They have also opened a whole new world to web developers. In fact, thanks to the rise of needs derived from the use of mobile devices, a set of new APIs specifically created for them has been standardized.

In the last months I’ve introduced you to several APIs, such as the Web Notifications API and the Web Speech API. In this article I’ll describe a simple, yet useful API called Proximity API.

Introduction

The Proximity API defines events that provide information about the distance between a device and an object, as measured by a proximity sensor. This API was initially part of the the Sensor API, later split and become an independent API. The specifications of the Proximity API are considered stable because it reached the status of W3C Candidate Recommendation as of 1st October 2013.

If you’ve ever had or used a smartphone, which I assume you have, you’ve already seen this API in action.

Want an example? Think of your last phone call and what you did. You unlocked your smartphone, typed the number you wanted to call, and then tapped the “Call” button. Once done, you placed the smartphone near your ear and suddenly something magic happened, the screen turned off.

This is an action many smartphones perform to safe your battery, but what powered this feature was the Proximity API. When you place your mobile device near enough to your ear, the proximity sensor fires an event that is listened to by your smartphone, which in turn shuts off the screen.

On the web, we have other interesting use cases. Have you ever been driving while listening to music using a web service and had to stop it?

How painful was it to take your device and then manually stop the player? I guess the answer is “A lot!”. Thanks to this API, web developers can now add a feature so that if an object (the hand in this case) is close to the device the player will pause.

Now that we know what the Proximity API is and its use cases, we can dive into the events it exposes.

Events

The Proximity API defines two events that we can listen to and react to based on the proximity of an object. The first event is deviceproximity and provides information about the distance between the hosting device and a nearby object. The second event is userproximity and specifies if the device has sensed a nearby object. Both fire on the window object, so to listen to them we attach a handler to it.

An example of how to attach a handler for the deviceproximity event is below:

window.addEventListener('deviceproximity', function(event) {
   console.log('An object is ' + event.value + ' centimeters far away');
});

The handler attached receives an object as its first parameter containing the info we need. The object passed by the deviceproximity event offers three properties: value, min, and max. value is a number that represents the proximity of the device to an object in centimeters. The min and max properties describe the minimum and the maximum distance the sensor can detect, in centimeters. The object passed by the userproximity event exposes the near property. It’s a boolean that specifies if an object is close enough to the device (true) or not (false). In this case close enough means the object is within the detectable range for the specific device.

Excited about this API? Not so fast…

Browser Compatibility

The support for the Proximity API is very low at the moment. The only browser that supports it is Firefox, both on desktop and mobile, starting from version 15. This is strange considering that it has already reached the status of W3C Candidate Recommendation but this is what we have for now.

Because this API has been implemented only in Firefox, knowing how to test for its support is crucial. We can do that using a well-known method that you may have encountered when dealing with other APIs. This method is shown below:

if ('ondeviceproximity' in window) {
   // API supported. Don't get too close, I can feel you
} else {
   // API not supported
}

As shown above, we can test the support of the userproximity event. At this point, we know what the Proximity API is and what events it exposes. To complete our journey, we’ll develop a simple demo to see it in action.

Demo

The demo we’ll build in this section attaches a handler to the deviceproximity and userproximity event and shows the value returned on the screen. To show the values, we’ll use an unordered list. Also, we’ll place two span tags at the beginning of the page to specify if a given event is not supported. By default they are hidden but if the browser doesn’t support an event they will be shown.

The JavaScript code is also simple. Firstly we test the browser to see if it supports the Proximity API. Because the latter comprises of two independent events, we’ll test them once at a time. If a given event isn’t supported, we show the relevant message to the user using the associated . Otherwise, we attach a handler so that we can retrieve and then show the values returned.

The source code of the demo is below, but you can also play with a live demo. This API is part of my HTML5 API demos repository, a collection of demos that allows you to play with dozens of APIs introduced by HTML5 and the related technologies.

<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
      <meta name="author" content="Aurelio De Rosa">
      <title>Proximity API Demo by Aurelio De Rosa</title>
      <style>
         *
         {
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
         }

         body
         {
            max-width: 500px;
            margin: 2em auto;
            padding: 0 0.5em;
            font-size: 20px;
         }

         h1
         {
            text-align: center;
         }

         .api-support
         {
            display: block;
         }

         .hidden
         {
            display: none;
         }

         .value
         {
            font-weight: bold;
         }

         .author
         {
            display: block;
            margin-top: 1em;
         }
      </style>
   </head>
   <body>
      <h1>Proximity API</h1>

      <span id="dp-unsupported" class="api-support hidden">deviceproximity event not supported</span>
      <span id="up-unsupported" class="api-support hidden">userproximity event not supported</span>

      <ul>
         <li>
            An object is at a distance of <span id="dp-value" class="value">null</span> centimeters
            (within a detectable range of <span id="dp-min" class="value">null</span> -
            <span id="dp-max" class="value">null</span> centimeters).
         </li>
         <li>
            Object close to the device? <span id="up-value" class="value">unavailable</span>
         </li>
      </ul>

      <small class="author">
         Demo created by <a href="http://www.audero.it">Aurelio De Rosa</a>
         (<a href="https://twitter.com/AurelioDeRosa">@AurelioDeRosa</a>).<br />
         This demo is part of the <a href="https://github.com/AurelioDeRosa/HTML5-API-demos">HTML5 API demos repository</a>.
      </small>

      <script>
         if (!('ondeviceproximity' in window)) {
            document.getElementById('dp-unsupported').classList.remove('hidden');
         } else {
            var proximityValue = document.getElementById('dp-value');
            var proximityMax = document.getElementById('dp-max');
            var proximityMin = document.getElementById('dp-min');

            window.addEventListener('deviceproximity', function(event) {
               proximityValue.innerHTML = event.value;
               proximityMax.innerHTML = event.max;
               proximityMin.innerHTML = event.min;
            });
         }

         if (!('onuserproximity' in window)) {
            document.getElementById('up-unsupported').classList.remove('hidden');
         } else {
            var inProximity = document.getElementById('up-value');

            window.addEventListener('userproximity', function(event) {
               inProximity.innerHTML = event.near;
            });
         }
      </script>
   </body>
</html>

Conclusions

In this article I introduced you to the Proximity API. We’ve seen what this API does and its use cases. We’ve discussed the events provided and how we can use them to adapt the behaviour of a web application based on the presence of an object near a device. Unfortunately, this API is only supported by Firefox so it may not be the time to use it yet.

What do you think about this API? Do you find it useful? Will you employ it in your next project?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • M S

    Cool!
    But how is this proximity actually measured?

    • Aurelio De Rosa

      The measure and its accuracy are sensor-specific so developers don’t have control over it. You can just read the data and act based on them.

  • thetrystero

    What is the equivalent of this API in the Android SDK? I’m guessing the example you mentioned with bringing the phone close to ear is done with the Android SDK no?

  • Britton.Stanfill

    I think this could be pretty interesting from and interaction design standpoint. I don’t know that I will be using this any time soon, all of my current projects probably wouldn’t benefit from using this API. And the fact that currently the API is only being implemented by Firefox right now would also be a blocker for me too.

    • Aurelio De Rosa

      Hi Britton.

      I can see your point. This API has very interesting use cases but it’s not for every project. About the limited support, the fact is that every browser vendor has to invest a lot yet limited resources to implement several features, fix bugs, add new APIs, new HTML elements, and so. Because of this, every company plans what’s a major priority and what’s not, hence the differences in the implementation time.

      However, I suspect that we’ll not wait many months before this API will be supported by all major browsers.

  • Aurelio De Rosa

    I’m not sure what you’re asking here. However, if you’re asking if the sensor detects two objects which one is chosen, my guess is “the nearest one”.

    • http://bvjebin.blogspot.com bvjebin

      Thanks for answering. Sorry for the unclear question. I got confused a little about the api and its working. I thought we can target a specific object and identify the proximity. But it doesn’t work that way. Instead it identifies if anything is within proximity. Nice intro.