DEV Community

Cover image for Managing lights in Android 12
Thomas Künneth
Thomas Künneth

Posted on • Updated on

Managing lights in Android 12

The final release of Android 12 is still months away, but the developer previews are packed with interesting new apis. Some of them have already been officially introduced, others not yet. In this piece I will focus on one of the latter ones, package android.hardware.lights (which is present since dp3). Browsing through the api difference report I stumbled upon android.hardware.lights.Light. The docs currently say:

Represents a logical light on the device.

We have four constants

  1. LIGHT_TYPE_INPUT_PLAYER_ID
  2. LIGHT_TYPE_INPUT_RGB
  3. LIGHT_TYPE_INPUT_SINGLE
  4. LIGHT_TYPE_MICROPHONE

and a bunch of query methods, for example getId() (returns the id of the light), getName() (the name of the light) and getType().

So, where do we get instances from? The usual suspect on Android is a manager obtained from getSystemService().

Let's take a look...

android.hardware.lights.LightsManager

class allows control over device lights

We have three methods, getLightState(Light light), getLights() and openSession().

We can wire things up like this:

getSystemService(LightsManager::class.java)?.run {
  lights.forEach { light ->
    println("name: ${light.name}")
    val state = getLightState(light)
    print("color: ${state.color.toString(6)}")
  }
}
Enter fullscreen mode Exit fullscreen mode

The state returned by getLightState() is an instance of android.hardware.lights.LightState.

The docs say:

Represents the state of a device light.

Controlling the color and brightness of a light is done
on a best-effort basis. Each of the R, G and B channels
represent the intensities of the respective part of an RGB
LED, if that is supported. For devices that only support on
or off lights, everything that's not off will turn the
light on. If the light is monochrome and only the
brightness can be controlled, the RGB color will be
converted to only a brightness value and that will be used
for the light's single channel.

Sounds like cool stuff. 😎

My example uses getColor(). The method returns

the color and intensity associated with this LightState

If I run this code without further preparations, I get a SecurityException.

A LogCat snippet

We need to add a android.permission.CONTROL_DEVICE_LIGHTS to the manifest. Trouble is... It's not there yet.

Screenshot showing a portion of the docs

In an attempt of not giving up too early I tried passing the string to the manifest nontheless:

<uses-permission android:name="android.permission.CONTROL_DEVICE_LIGHTS" />
Enter fullscreen mode Exit fullscreen mode

Still got the exception. Hm. Maybe it's a dangerous permission...?

val requestPermissionLauncher =
  registerForActivityResult(
    ActivityResultContracts.RequestPermission()
  ) { isGranted: Boolean ->
    if (isGranted) {
      doIt()
    }
  }
when {
  ContextCompat.checkSelfPermission(
    this,
    "android.permission.CONTROL_DEVICE_LIGHTS"
  ) == PackageManager.PERMISSION_GRANTED -> {
    doIt()
  }
  else -> {
    requestPermissionLauncher.launch(
      "android.permission.CONTROL_DEVICE_LIGHTS"
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

Did not make a difference, either.

So, for now I just assume that I am either doing something wrong, or some things still need to be added. In any case, looking forward very much to get the new feature, as it sounds like fun. Especially changing lights and using sessions seems nice. Will be interesting to see if this will be doable in the emulator, too. 😎

Do you like such early investigations? Please share your thoughts in the comments.

Top comments (0)