Android Light Sensor to detect significant light change

3.7k Views Asked by At

I am trying to use Sensor.Type_Light or the Light Sensor to detect change in event.values[0].

@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType()== Sensor.TYPE_LIGHT) {
        debugView = (TextView)findViewById(R.id.lightValue);
        debugView.setText("Detecting...." +event.values[0]);
    }

As you can see, The values are displayed in a TextView. Also, we know that if event.values[0] is 0, there is no light and as the light increases, the value also increases. Now my question is: How can I use this event.values[0] to detect significant change in light that is, if I activate my Sensor in adequate light (event.values[0] >15), it should be able to trigger an event when light turns off (event.values[0] < 3) and vice-versa.

Thanks in advance

I tried the following in onSensorChanged, but nothing seems to work.

if(event.values[0] >= 0 && event.values[0] <5) {
    // No Light
    if(event.values[0] > 10) {
        callForHelp();
    }
}
else {
    if(event.values[0] > 15) {
        // Light On
        if(event.values[0] < 5) {
            callForHelp();
        }
    }
}
3

There are 3 best solutions below

1
On

Inside onSensorChanged(), why don't you do exactly what you say you want:

if (event.values[0] > 15) {
    trigger_some_event();
}
else if (event.values[0] < 3) {
    trigger_another_event();
}
1
On

=> Xml file layout to show Image on Screen

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView
            android:id="@+id/imgWallpaper"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:padding="5dp"
            android:src="@drawable/ic_img" />
    </RelativeLayout>

=> Activity code

    import android.app.Activity;
    import android.content.Context;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.Bundle;
    import android.widget.ImageView;
    public class WallpaperChangeByLight extends Activity {
        SensorManager sensorManager = null;
        Sensor light = null;
        float sensorValue = -1;
        ImageView imgView = null;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.content_main);
            imgView = (ImageView) findViewById(R.id.imgWallpaper);
            sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
            light = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
            sensorManager.registerListener(new SensorEventListener() {
                @Override
                public void onSensorChanged(SensorEvent event) {
                    if (event.sensor.getType() == Sensor.TYPE_LIGHT) {
                        if (event.values[0] < 3 || event.values[0] > 15) {
                            sensorValue = event.values[0];
                        }
                        if (sensorValue < 3) {
                            imgView.setImageDrawable(getDrawable(R.drawable.ic_nolight));
                        } else {
                            imgView.setImageDrawable(getDrawable(R.drawable.ic_light));
                        }
                    }
                }
                @Override
                public void onAccuracyChanged(Sensor sensor, int accuracy) {
                }
            }, light, SensorManager.SENSOR_DELAY_NORMAL);
        }

    }

DO NOT FORGET TO PUT DRAWABLE IMAGES (ic_nolight.png, ic_light.png)

0
On

Your problem is that you only want to react when there is a significant change.

The solution where you simply check the value in the onChanged method will not work as a change from the value "3" to the value "0" is not a significant change, yet it will be detected.

What you need is simply a variable to remember the value from the previous light event.

Declare a variable on the activity scope (not inside the event callback) and call it something like "previousLightValue"

then in the onSensorChanged method you can compare event.values[0] to the previousLightValue variable and only "react" if the change is above a certain threshold that you decide on.

You can also check if the value has gone down or up since the last measurement, telling you if the light is now brighter or darker.

Just remember that you need to initialize the "previousLightValue" variable before you can use it for comparison. So detect the first occurance of the onSensorChanged event and only store the value in "previousLightValue", without doing the check. From then on, you are good to go.