Search TheCodeArtist

Loading...

Proximity Sensor on Android Gingerbread

The proximity sensor is common on most smart-phones, the ones that have a touchscreen. This is because the primary function of a proximity sensor is to disable accidental touch events. The most common scenario being- The ear coming in contact with the screen and generating touch events, while on a call.

To solve the "I didn't take that stupid picture, my ear did" issue, device manufacturers came up with the idea of a placing a proximity sensor close to the speaker, which will then detect any object in the vicinity of the speaker. If any object is present (ex. user's ear), then the touch events can be assumed to be accidental & ignored.

Now there are various technologies for proximity sensing:
  • Electrical (Inductive, Capacitive)
  • Optical. (IR, Laser)
  • Magnetic.
  • Sonar.
Of all these, the most non-intrusive and low-cost modules are the optical proximity sensors. These can detect bodies in the vicinity of the device upto 5cm. This is perfect for use on smart-phones.

Coming to Sensors on Android-Gingerbread, the proximity sensor is often implemented using a light sensor chip. Common ones are ISL29003/23 & GP2A by Intersil & Sharp respectively. Both these sensor-chips are primarily active light sensors, which provide the ambient light intensity in LUX units.

The distance value is measured in centimeters. Note that some proximity sensors only support a binary "close" or "far" measurement.  In this case, the sensor should report its maxRange value in the "far" state and a value less than maxRange in the "near" state.

Let us take an example. Say the device uses a GP2A chip placed close to the speaker facing the user (as shown in the adjoining pic). The normal  light response of the GP2A is such that it triggers a proximity-detect interrupt at a distance of approximately 5cms in normal lighting.

This means that when the user receives a call and brings the phone closer to his ear, the ambient-light around the light/proximity-sensor slowly drops down below the threshold & the sensor detects this and switches the state from FAR to NEAR. This event can be detected by any android application which has registered a SensorEventListener.

In most Android phones, the proximity sensor is implemented as a boolean-sensor. Its returns just two values "NEAR" & "FAR". Thresholding is done on the LUX value i.e. the LUX value of the light sensor is compared with a threshold. A LUX-value more than threshold means the proximity sensor returns "FAR". Anything less than the threshold value and the sensor  returns "NEAR". The actual value of threshold is custom-defined depending on the sensor-chip in use and its light-response, coupled with the location & orientation of the chip on the smart-phone body.

The proximity sensor is implemented very much like the other sensors except on one critical point -
Proximity sensor is interrupt-based (not Poll-based).
All the other sensors are polled for at regular intervals, selected by the DELAY parameter used while registering a SensorEventListener. Proximity Sensor is interrupt based (NOT polling). This means that we get a proximity event only when the proximity changes (either NEAR to FAR or FAR to NEAR).

__________________________

Further Reading:


62 comments :

  1. Really an useful info.

    ReplyDelete
  2. Nice informative piece! Thank you!

    ReplyDelete
  3. "A LUX-value more than threshold means the proximity sensor returns "FAR". Anything less than the threshold value and the sensor returns "NEAR"." is one of the methods of implementation of proximity sensor.

    If the above method as described is used in smartphones, how does the proximity feature work on 'call' during nights ?

    During night, ambient light sensor detects very low lux value which falls below the threshold value. But this shouldnt trigger a "NEAR" interrupt when the phone is away.

    ReplyDelete
    Replies
    1. A very good point.

      This situation is handled by "active" proximity-sensors that have a light-source embedded in the module itself. This is usually an LED that emits light in the Infrared(non-visible) spectrum.

      An object in the near vicinity of the proximity-sensor reflects a good amount IR light back to the sensor. This is used to signal a "NEAR" interrupt. As the object is moved away, the amount of IR light reflected back reduces. Once this falls below a threshold, the "FAR" interrupt is raised.

      Detailed diagram:
      Proximity sensor hardware on Android.

      Delete
  4. Is there any way to restart the service or process that runs the proximity sensor on android 2.3.5? reason i ask is, whenever i make a bluetooth connection, then disconnect the connection, and return to normal phone-to-face use, the sensor no longer operates until i reboot the phone.

    ReplyDelete
  5. The sensorservice would be a thread running as part of systemserver. Nothing short of a reboot (or killing systemserver, so that it restarts automatically) will "reset" this. This doesn't seem to be a standard issue though. GB2.3.7 on N1 seems to do fine in the above scenario. May i know the device/ROM where you see the issue?...

    ReplyDelete
  6. I am coding an Android App that uses ambient light sensor. My problem is: when my java code is checking for the light sensor, it says that their is "no light sensor present". However, my phone has an ambient light sensor, and it works fine. Can someone help me out? maybe i missed some permission on the manifest file.


    Thanks in advance...

    ReplyDelete
    Replies
    1. On some devices the ambient-light-sensing hardware is present but the kernel-driver & sensor-HAL are written to provide only a boolean proximity-sensor as this is sufficient to disable/enable the screen during a call.

      Can you call getSensorList() in your application and see if the reported list contains a light sensor?

      Which Android phone/tablet are you trying this out on?

      Delete
    2. Thanks for that info Chinmay,

      I haven't tried that yet but i tried running it on LG E400 and samsung galaxy y and experiencing the same trouble.

      Delete
    3. Unfortunately both LG-E400 and Samsung Galaxy-Y provide ONLY proximity-sensor data with the default factory-ROM.

      Delete
    4. how can i deal with that? i mean, what should i use in my code? how can i use its light sensor for the brightness of the screen?

      btw

      I am using Sony Ericsson ST15i, on its technical specs, it has an ambient light sensor.

      Delete
    5. A quick and definitive way of testing for ALS support on any device would be calling getSensorList() in an app(sensors-release.apk) on the device. ALS will be supported using Android sensor APIs if and ONLY if a "light-sensor" returning LUX values is listed in the list of sensors getSensorList returns.

      If present one can then go ahead and obtain an handle to the light-sensor using standard Android sensor APIs and carry on from there.

      If NOT present, then the options would be to see if the OEM has devised any alternative methods(cat sysfs etc.). If not, then searching for custom kernel/ROMs with ALS support for the device is the last alternative. This in turn will require rooting the device.

      Try running sensors-release.apk on the device. The app calls getSensorList() and displays the list of sensors detected on the screen.

      Delete
    6. Thanks again Chinmay,,, ill use this app to check. Ill get back to you.

      Delete
    7. Another thing Chinmay, if I root my phone, should i need to change my java code? I mean is their a different
      method to ACCESS that said light sensor?

      Delete
    8. Apart from the android sensor APIs there is no documented standard across devices/ROMs.

      AFAIK, there are very few Android devices that do provide ALS. Most low-end devices just provide a proximity sensor(though on some the hardware supports proximity+ALS).

      IF a device does NOT list a light-sensor in getSensorList(), but provides ALS functionality like automatic brightness adjustment of the display-backlight, then it would mean that a custom method has been implemented on the device/ROM for the light-sensor. To use this one would definitely need to change the java code in the app.

      Now here is the deal(LOTs of work):
      + IF device has ALS hardware,
      + IF ALS hardware datasheets are available,
      + IF device is rooted,
      + IF device android/kernel source is available,

      Then one could actually go ahead and implement the ALS functionality in the kernel-driver and the sensor-HAL. The software support for sensors is present in the sensor-HAL on the device:
      /system/lib/hw/sensors..so
      This would need to be modified and rebuilt. Then once the modified kernel and sensor-HAL are copied onto the device, (which is what custom-ROMs developers do) getSensorList() will list a light-sensor and standard Android sensor APIs will work properly i.e. no change is java code.

      Delete
  7. Thank you so much for that info and for the support...

    ReplyDelete
  8. It is a very nice blog posted that provide me information regarding the proximity sensor on Android gingerbread and i know how it works. So thanks for sharing this kind of information.

    ReplyDelete
  9. Great info! keep up the good work and knowledge sharing..

    ReplyDelete
  10. Thanks for the info! i didn't know what it was for, now i know thx!

    ReplyDelete
  11. Great information about Proximity Sensor.

    I use it for lock/unlock screen on my phone using an Android App. It works like a charm.

    Again Thanks

    ReplyDelete
  12. Hi brother just a quick advise m using samsung note 2 and I have a red dim light on the top of my hp is that proxm.device as mention and how do we switch off whats ur advise what are the pros n cons of these app. Thank u

    ReplyDelete
    Replies
    1. Are you sure its not the notification LED that is blinking red? Note2 does have a notification LED near the front-cam and the proximity sensor. You can use apps like "Lightflow" to configure the notification LED.

      Delete
  13. Thanks for the great information, very useful.
    I am looking for a way to avoid accidental touch events for my Android app and considering using the proximity sensor as used during a call.
    My question: assuming my application is in the front most of the day (I am a launcher type application), and i will use the proximity sensor all the time the screen is ON to disable/enable the screen - is it going to drain my battery much faster?

    ReplyDelete
    Replies
    1. The Light/Proximity sensor hardware has a current draw of about 20-30mA. Assuming a 1000mAh battery on the mobile device, it amounts to 2-3%(per hour) additional battery drain by the enabling the proximity sensor.

      Delete
    2. I am planning to use the sensor while the screen is ON only (in order to turn it OFF when get into the pocket and not while the screen is OFF).
      does it change the above numbers or this is your assumption as well?
      Assuming the phone battery relevant duration is from 07 am to 09 pm (14 hours) - does it mean the sensor alone will use about 2-3% * 14 (around 35%)?
      Thanks again for your help!

      Delete
    3. Tl;DR:
      Proximity sensor does NOT draw power when the phone is allowed to enter suspend mode i.e no active wakelocks and screen-timeout occurs or user taps the power button.

      Longer Version:
      Lets look at this from a usability perspective. Once the phone is in the pocket(and since your receive a proximity event, turn-off the display), what next?

      Option1. Unregister the proximity sensorEventListener?
      - This will result in power savings due to the light/proximity peripheral hardware being turned-off.

      Option2. Continue using the proximity sensorEventListener?
      - Allows another layer of "smart" to the launcher app. The display can be turned on when phone is taken out of the pocket.

      But to use option2 the device could never be allowed to completely enter suspend i.e only the screen can be allowed to switch-off but you would need to acquire a partial wakelock alongwith the proximity sensorEventListener. This is very inefficient in terms of power, and hence NOT recommended.

      Thus we can stick with Option1 i.e. allow the phone to enter suspend mode when in the pocket. This means that all the peripherals(including the proximity sensor) are powered-down. Thus there will NOT be any additonal drain as long as the phone is in the pocket and is allowed to enter standby(no wakelocks held).

      So if the phone spent 7am-9pm in the pocket there would be no change in the power drain. A more realistic assumption would be that the user uses the phone half the time and its in the pocket for the remaining half i.e. 7hrs each. This would mean that about about 200mAh of battery would be consumed by it. This is about 20% of low-end phones which have 1000mAh batteries. High-end phones have battery capacities closer to 2000mAh; meaning the above feature would end up consuming atleast an additional 10% in a routine day.

      Delete
    4. first i need 2 thank you for sharing your views and idea. I have simple query, when user go near to proximity during phone call, android shutdown the screen. But this call "early suspend" implemented for the "proximity sensor driver". So this causes my sensor to disable during phone call and screen remain blank out even though call been ended. Due u ve any suggestion or workaround for this scenario.

      Delete
    5. Short of modifying the driver in the kernel or using a ROM that has such a fix, i can't think of any other workaround.

      Delete
    6. Thanx Chinmay, I have another query - what is mean by proximity calibration, what it does during calibration process?.

      Delete
    7. The "proximity-calibration" process is usually done by the hardware manufacturer or the device OEM. It involves setting a threshold distance. Any object within the threshold triggers the proximity sensor's output to 1. No objects within the threshold revert the proximity sensor's output to 0.

      As all Android smartphones/tablets invariably use light/IR based proximity sensors, the "calibration process" involves setting a LUX-value(intensity of light/IR) in the light/proximity sensor hardware on the device.

      Delete
  14. Is it possible to set the proximity sensor to turn off the screen when the sensor completely covered or almost completely?
    currently, I downloaded nice app from Google Play to test the options but it turn off the screen even when my finger is about 0.5 cm above the sensor.
    any other way to handle this problem?

    ReplyDelete
    Replies
    1. The distance at which the proximity sensor triggers is either controlled in the sensor HAL(part of the Android OS framework). It is NOT exposed to the application as a configurable parameter.

      Also the hardware on certain device is NOT configurable at all. Rather it will trigger a proximity interrupt at a pre-defined fixed distance.

      Measuring the distance of a nearby object can be accomplished using the light sensor(same physical hardware on the device). Any object in the near vicinity casts a shadow and reduces the ambient light intensity. But this will have to be carefully calibrated and would work ONLY as long as the source of light does NOT change.

      Delete
  15. Can the light sensor detect a specific color?
    I was thinking if possible to have a specific color cover (such as blue/red etc.) and have a logic that only if phone is covered with blue color than turn the screen off.

    ReplyDelete
    Replies
    1. The light sensing hardware in current Android phones measures only intensity of light and cannot differentiate between various colors.

      Some are calibrated to be more sensitive to IR(and near IR) wavelengths. This is mainly for proximity sensing even in the dark. But apart from that all colors register similarly.

      If the light source characteristics were controlled/known, then one could try to diffrentiate between lighter/darker colors or shades of gray. As the lighter colors absorb less and reflect more of the incident light, they would register brighter on the light-sensor. Extreme care/calibration would be needed though to obtain a working setup.

      Delete
  16. Very nice,very informative.I enjoyed reading the article.Keep up the great work bro!

    ReplyDelete
  17. Came across this page trying to find a solution for my EVO 4G LTE's prox sensor problem. What I've discovered, besides that it's more likely to register a false NEAR in my car, is that exposure to bright light will always trigger a false NEAR event when it's removed. That can often be cleared by turning the screen off with power button, but not always. Any thoughts on if that indicates a problem with the hardware or possibly is still a software issue?

    ReplyDelete
    Replies
    1. You can start by wiping off any smudges over the proximity sensor. Also if you hav applied a screen-protector, ensure that it has dual-cutouts- one for the sensor and the other of the IR emitter 1/3" beside it.

      If the problem persist then its surely an issue with your device.

      Also the general consensus among HTC EVO 4G LTE users is that the proximity sensor response has improved (sensitivity to light has increased) after upgrading to Android-JB.

      Delete
    2. It's clean, without a screen protector. I guess it's back to the Sprint store. Wish me luck!

      Delete
  18. Please check Air Control app which uses Proximity sensor.

    https://play.google.com/store/apps/details?id=in.tank.corp.proximity

    ReplyDelete
  19. very useful info..
    bt in my mobilephone-spicce-Mi-491, the call an be answered just by picking up the phone, and the call can also be moved to silence by just reversing the side of phone..is the same sensor used in this feature too??

    also this creates a problem-
    when there's a call in waiting, i see the contact nd again hear to previous call, bt it automatically holds up the prev. call nd picks up the call in waiting..is this feature too due to the same???

    pls. reply soon
    thnx..

    ReplyDelete
    Replies
    1. The spice-Mi491 tech-specs do not mention any proximity sensor. This feature of detecting the orientation of the device can be implemented using the accelerometer hardware(which IS present on Mi491).

      And yes, both the use-cases you mention will be triggered by the device orientation changing.

      Delete
  20. Thanks man,
    Nice article, then again nice comments with Informative replies.
    Good job, keep it up.
    God bless.

    ReplyDelete
  21. Hi Chinmay

    Thanks for the nice information
    I have a doubt concerning the polling rate of the sensor. As your article does suggests that it is interrupt based, so therefore it may not require any polling. However while implementing it in the code I do need to register to the SensorEventlistener therefore I do need to use the Sensor_delay_fastest or Sensor_delay_normal, etc. that are synonymous to the way in which samples are generated or managing the delay amongst samples.

    So, therefore I wanted to ask you that why do we use these Sensor_delay_fastest or Sensor_delay_normal, etc in the case of proximity sensors.

    Thanks
    Shashank

    ReplyDelete
    Replies
    1. The API specifies that the application receives the "event" only in case of a change in proximity (from far to near or vice-versa) and not repeatedly at regular intervals.

      However, the proximity sensor is invariably implemented on Android smartphones using a light-sensor. The rate parameter is used to internally to set the rate of polling the light sensor in the kernel driver.

      Delete
    2. Chinnay, thanks. Can you please explain a bit more as what do you imply by

      " The rate parameter is used to internally to set the rate of polling the light sensor in the kernel driver"

      But in an all we are polling the proximity sensor that it is implemented by light sensor though. However, we are polling it, so how does the interrupt based concept fits in. Suppose if I say if I am registering my event listener to proximity sensor at the fastest rate (Sensor_delay_fastest) then what exactly does it refers in context of light sensor.

      Please give a detailed explanation
      Thanks
      Shashank

      Delete
    3. From an application developer's perspective, it is safe to assume that the the polling-rate is NOT really used at all and the app will receive the sensorEvent whenever a transition between near and far states occurs on the proximity-sensor hardware.

      However on certain Android devices the low-end light-sensor hardware used does not have such a interrupt feature to detect a user-configured threshold. Also certain OEMs prefer to implement their own logic to detect proximity which also takes into account the ambient-light LUX values. In both these cases, the kernel will be programmed to poll the light sensor at the polling-rate parameter specified. However, even in this case, the app will be passed a sensorEvent ONLY in case of a near<-->far transition i.e the app still sees a "interrupt-on-threshold-transition" behaviour.

      You can test how it is implemented on any given Android device by registering a proximity sensorEventListener and logging the time-stamp each proximity-event arrives in your app. Always try to generate proximity events at a very fast rate by waving/snapping your finger in front of the sensor. If the frequency of proximity events varies with the polling-rate specified, then you can be assured that the kernel is indeed polling the light-sensor(and not registering a hardware interrupt) and reporting proximity-events to the app whenever a transition between successive polled values occurs( in order to simulate an interrupt-based behaviour).

      Delete
    4. Hi Chinmay

      Thanks for clarification.
      I was wondering about the location of the sensors in the hardware kit of the smartphone. Do you have any idea where are the sensor are exactly placed in a smartphone kit. I am pretty sure that the proximity sensor is placed near the speaker but do you have an idea where the gyroscope and accelerometers are placed, or if you have any reference where I could look for.

      Thanks
      Shashank

      Delete
    5. Location on PCB is not mandated anywhere specific. It differs for each Android device.

      The gyro IC is best placed close to the center of the PCB as the rotation of the device then matches with what is felt by the gyro IC.

      Also several hardware-vendors offer integrated accel-gyro-magnetometer ICs. These need to be placed as far away from the internal speakers (and any such electro-magnetic component) to minimise the interference(EMI) that reduces the accuracy of the magnetic-field readings.

      Delete
  22. HI Chinmay

    Thanks for wonderful tutorial, I was working on the accelerometer and gyroscope sensor and I simply wrote the values from both sensors into a csv files alon with the timestamped values. I noticed that there is some time lag between the values written from the two sensors though I have programmed them to work in their fastest mode and the clocks are also synchronized. Can you explain a bit about it, why is there a time lag between the values.

    Thank you
    Kartik

    ReplyDelete
    Replies
    1. SENSORS_DELAY_FASTEST implies the fastest mode for the individual sensor. This is different for accel and gyro. The gyro and accel sensors are physically different hardware. Gyro is capable of a faster rate of samples compared to the accel (refer limitations of MEMS).

      Also as accel and gyro are often handled by different kernel drivers, it is very natural that the events are not received simultaneously from the kernel.

      Delete
  23. Thanks, was of good help :)

    ReplyDelete
  24. Hi Chinmay V S ! Very useful article. I have a doubt. Imagine a situation where an app does use the proximity sensor to provide a screen unlock functionality. In this situation, the sensor will be working all the time. Beyond the power consuption problem, this intense use of the sensor can cause a hardware problem, because of prolongated use ? Imagine that the phone is powered-on all the time, and the sensor stay active all the time. This can cause problems to device, like "burn" the sensor, for example ? Thank you !

    ReplyDelete
  25. Hi Chinmay V S ..Nice article. I have one issue regarding LCD on/off using sensor events. Kernel is sending signals based on object detection of near/ far events. But if sensor get events continuously say 500ms difference only how to handle the LCD On/OFF method. Because my device LCD is flickering as events trigger continuously.

    ReplyDelete
    Replies
    1. Usual method to solve this is to implement hystersis. For example if we dfine the proximity boundary at 5.0 and the value of proximity X(in cms) constantly oscillates between 4.5 to 5.5 then configure the driver to report

      X < 4.5cm as near event.
      4.5 < X < 5.5 (no events reported)
      X > 5.5cm as far event.

      By choosing the range of hystersis (in this case 4.5 to 5.5) properly, we can prevent the triggering of continuous alternating near and far events.

      Another simpler (but less effective) method is to ignore subsequent events for a fixed time period immediately after an event occurs.

      Delete
    2. Thanks Chinmay !! ..

      Delete
  26. Hi chinmay, my device has a proximity sensor and it doesn't support light sensor.the sensor is gp2a and my device is galaxy core. Can u tell me whether it can be coded to use as a light sensor also?

    ReplyDelete
    Replies
    1. Yes. Several variants of GP2A by Sharp support Ambient light sensing in the hardware. You will find this driver useful as a reference.

      Delete
  27. wow that`s really helpful

    ReplyDelete