Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect user presence in android?

I know in Galaxy Samsung SIII it is possible to configure in settings an option to avoid the screen turns off when user is looking into the screen. I think the phone uses the camera or a kind of a sensor of presence.

  1. is it possible to do it programmatically?
  2. even if yes, some devices won't be capable to do that. I imagine some possibilities here: using the camera, accelerometer, or even user activity: if the screen is on, touches, I don't know. There is a specific library about "user presence" to android? Using the best of all sensors when available?
like image 891
Felipe Avatar asked Dec 19 '12 15:12

Felipe


1 Answers

Yes, there's something like that.

You can use SensorManager to get sensor events. For example, Light Sensor will be usefull for you:

private SensorManager sensorManager;
private Sensor lightSensor;
private float lightAmount;

public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
     sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
     lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

     SensorEventListener listener = new SensorEventListener() {
         @Override
         public void onSensorChanged(SensorEvent event) {
             // returns the current light amount
             lightAmount = event.data[0];
         }

     lightSensor.registerListener(listener);
}

But of course he can't do all the job alone. Program your light sensor to see when the screen becomes brighter, if true that should mean the user is no longer looking to it. And you can use the accelerometer (as you said) to help you out. I found some code and adapted it, the class should be something like this:

public class AccelerometerDetector {

    boolean isAvailable = false;
    boolean isEnabled = false;

    /**
     * Constructor.
     *
     * @param enable : True to enable the accelerometer
     * @throws UnsupportedOperationException
     *  - thrown if the Accelerometer is not available on the current device.
     */
    public AccelerometerDetector(boolean enable) 
            throws UnsupportedOperationException 
    {
            /* Check if the sensor is available */
            for (String accelerometer : Sensors.getSupportedSensors())
                    if (accelerometer.equals(Sensors.SENSOR_ACCELEROMETER))
                            isAvailable = true;

            if (!accelerometerAvailable)
                    throw new UnsupportedOperationException(
                                    "Accelerometer is not available.");

            if (enable)
                    setEnableAccelerometer(true);
    }

    /**
     * Set if the Accelerometer is enabled or not.
     *
     * @param enable
     * @throws UnsupportedOperationException
     */
    public void setEnableAccelerometer(boolean enable)
            throws UnsupportedOperationException 
    {
            if (!accelerometerAvailable)
                    throw new UnsupportedOperationException(
                                    "Accelerometer is not available.");

            /* If should be enabled and isn't already */
            if (enable && !this.isEnabled) {
                    Sensors.enableSensor(Sensors.SENSOR_ACCELEROMETER);
                    this.isEnabled = true;
            } else /* If should be disabled and isn't already */
            if (!enable && this.isEnabled) {
                    Sensors.disableSensor(Sensors.SENSOR_ACCELEROMETER);
                    this.isEnabled = false;
            }
    }

    /**
     * Read the values provided by the Accelerometer.
     *
     * @return Current Accelerometer-values.
     * @throws UnsupportedOperationException
     *             if the Accelerometer is not available on this device.
     * @throws IllegalStateException
     *             if the Accelerometer was disabled.
     */
    public float[] readAccelerometer() 
            throws UnsupportedOperationException, IllegalStateException 
    {
            if (!isAvailable)
                    throw new UnsupportedOperationException(
                                    "Accelerometer is not available.");

            if (!this.isEnabled)
                    throw new IllegalStateException(
                                    "Accelerometer was disabled.");
            /* Get number of sensor-values the sensor will return. Could be
             * variable, depending of the amount of axis (1D, 2D or 3D
             * accelerometer). */
            int sensorValues = Sensors
                            .getNumSensorValues(Sensors.SENSOR_ACCELEROMETER);
            float[] values = new float[sensorValues];

            /* Make the OS fill the array we passed. */
            Sensors.readSensor(Sensors.SENSOR_ACCELEROMETER, values);

            return values;
    }
}

Also declare this feature in your Manifest.xml:

<uses-feature android:name="android.hardware.sensor.light" />
<uses-feature android:name="android.hardware.sensor.accelerometer" />

What you called "Presence Sensor" might be the Light/Proximity Sensor. But you can't use the Proximity Sensor because it usually only has 5cm range.

enter image description here

like image 172
Sergio Carneiro Avatar answered Sep 23 '22 11:09

Sergio Carneiro