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.
- is it possible to do it programmatically?
- 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?
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.
You can use device's front camera to detect user's face and hence check the presence of the user. The good thing is this can work on any android phone with the front camera.
Here is the library from GitHub that demonstrates how you can achieve it using Google Play Services' Vission APIs.