Time for action – adjusting the screen brightness using the light sensor

One of the most common use cases for the light sensor is to adjust the screen brightness according to the external lighting conditions. The maximum range of the light sensor might be different on different Android devices, but most of them support from 0 lux to several thousand lux. Lux is the standard unit for measuring the luminance of the light falling on a surface. For our example, we will use a range from 0 to 100 lux, as normal indoor lighting falls within this range. But for sunlight and strong lights the range can go up to 1,000 lux or more. In the sample app, we will increase the screen brightness, when the indoor lighting goes low, and similarly we will decrease the screen brightness when it goes high.

  1. We followed the standard steps to get values from the sensor. We select the sensor type to the TYPE_LIGHT in the getDefaultSensor() method of SensorManager. We also called the custom initScreenBrightness() method from onCreate() to initialize the required content resolver and current window objects:

            public class LightSensorActivity extends Activity implements 
            SensorEventListener{ 
     
              private SensorManager mSensorManager; 
              private Sensor mSensor; 
              private boolean isSensorPresent; 
              private ContentResolver mContentResolver; 
              private Window mWindow; 
     
              @Override 
              protected void onCreate(Bundle savedInstanceState) { 
                super.onCreate(savedInstanceState); 
                setContentView(R.layout.lightsensor_layout); 
     
                mSensorManager = (SensorManager)this.getSystemService
                (Context.SENSOR_SERVICE); 
                if(mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) != null) 
                { 
                  mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); 
                  isSensorPresent = true; 
                } else { 
                  isSensorPresent = false; 
                } 
           
                initScreenBrightness(); 
            } 
    
  2. As a standard practice, we registered the listener in the onResume() method and un-registered it in the onPause() method. Inside the custom initScreenBrightness() method, we initialized the ContentResolver and Window objects. The ContentResolver provides a handle to the system settings and the Window object provides the access to the current visible window. In the onDestroy() method of the activity, we change all the initialized objects references to null:

            @Override 
            protected void onResume() { 
              super.onResume(); 
              if(isSensorPresent) { 
                mSensorManager.registerListener(this, mSensor, 
                SensorManager.SENSOR_DELAY_NORMAL); 
              } 
            } 
     
            @Override 
            protected void onPause() { 
              super.onPause(); 
              if(isSensorPresent) { 
                mSensorManager.unregisterListener(this); 
              } 
            } 
     
            public void initScreenBrightness() 
            { 
              mContentResolver = getContentResolver(); 
              mWindow = getWindow(); 
            } 
     
            @Override 
            protected void onDestroy() { 
              super.onDestroy(); 
     
              mSensorManager = null; 
              mSensor = null; 
              mContentResolver = null; 
              mWindow = null; 
            } 
    
  3. As discussed earlier, we will use a light range from 0 to 100 lux for our example. We will be adjusting the brightness for two objects: one for the current visible window (for which the brightness value lies between 0 and 1), and the second for the system preference (for which the brightness value lies between 0 and 255). In order to use the common brightness value for both the objects, we will stick to a value between 0 and 1, and for system brightness we will scale up by multiplying it by 255. Since we have to increase the screen brightness, as the outside lightening goes low and vice versa, we take the inverse of the light sensor values. Also to keep the range of the brightness value between 0 and 1, we use only light values between 0 and 100. We pass on the inverse of light values obtained from the light sensor in the onSensorChanged() method, as an argument to our custom changeScreenBrightness() method to update the current window and system screen brightness:

            public void changeScreenBrightness(float brightness) 
            { 
              //system setting brightness values ranges between 0-255 
              //We scale up by multiplying by 255 
              //This change brightness for over all system settings 
              System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, (int) 
              (brightness*255)); 
        
              //screen brightness values ranges between 0 - 1 
              //This only changes brightness for the current window 
              LayoutParams mLayoutParams = mWindow.getAttributes(); 
              mLayoutParams.screenBrightness = brightness; 
              mWindow.setAttributes(mLayoutParams); 
            } 
     
            @Override 
            public void onSensorChanged(SensorEvent event) { 
              float light = event.values[0]; 
              //We only use light sensor value between 0 - 100 
              //Before sending, we take the inverse of the value 
              //So that they remain in range of 0 - 1 
              if(light>0 && light<100) { 
                changeScreenBrightness(1/light); 
              } 
            } 
    

The app needs to have following three permissions to run the previous two examples:

  • <uses-permission android:name="android.permission.CAMERA" />
  • <uses-permission android:name="android.permission.FLASHLIGHT" />
  • <uses-permission android:name="android.permission.WRITE_SETTINGS" />

The camera permission is required to access the camera object, flashlight permission is required to turn on and turn off the flashlight, and the write settings permission is required to change any system settings.

What just happened?

We used light luminance values in lux (coming from the light sensor) to adjust the screen brightness. When it is very dark (almost no light), then the light sensor provides very low sensor values. When we send this low light sensor value (the minimum possible value being 1) to the changeScreenBrightness()method, then it makes the screen the brightest by taking the inverse (which is again 1) of the light sensor value and scaling up by multiplying it by 255 (1 * 255 = 255 brightness value). Similarly, under good lighting conditions, when we send a high sensor value (the maximum possible value being 99 in our case), then it makes the screen as dim as possible by taking the inverse (1/99=0.01) of the light sensor value and scaling up by multiplying it by 255 (0.01 * 255 = 2.55 brightness value). One of the easiest ways to test this app is to cover the light sensor with your hand or any opaque object. By doing this, you will observe that when you cover the light sensor, the screen becomes bright, and when you remove the cover, it becomes dim.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset