
Dealing with the Kinect status
The Kinect sensor needs an external power supply to get the camera, IR sensor, and motor to work properly. Even after following all the standard practices and measures, your system might not detect any of the components of Kinect if there is any problem with your device. Other scenarios that may occur, and that are indeterministic in nature, could be the power suddenly going off while your application is running, , some error occurring in the device, or the device getting unplugged. All the earlier cases can cause your application to crash or throw an unknown exception.
It is of paramount importance to track the device status while your sensor is used by the application. The KinectSensor
object has a property named Status
, which indicates the current state of the devices. The property type is of the KinectStatus
enumeration.
The following table has listed the different status values with their descriptions:

To understand the flow of the Kinect status and the scenarios in which it can occur can be explained in a simpler way refer to the following diagram. Once the device is connected and the power is turned off, it will show the NotPowered
status. Similarly, unplugging the device from USB port will return the Disconnected
status. If you plug it back in or turn the power on, it will first show the Initializing
status before changing to the Connected
status.

Monitoring the change in sensor status
The KinectSensorCollection
object has only an event named StatusChanged
, which can be registered as follows:
KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged;
Once the event is registered, it will fire automatically if there are any changes in the device status, internally or externally.
The StatusChanged
event fires up with a StatusChangedEventArgs
class, which holds the KinectStatus
property and the instance of the sensor by which this event has been raised.
The following table shows the properties of the StatusChangedEventArgs
class:

In the StatusChanged
event handler, you can check for the status that is returned by the KinectStatus
enumeration and display the proper message to end users. The uses of different statuses with the StatusChanged
event handler are shown in the following code snippet:
void Kinects_StatusChanged(object sender, StatusChangedEventArgs e) { switch (e.Status) { case KinectStatus.Connected: // Device Connected; break; case KinectStatus.DisConnected: // Device DisConnected; break; } }
So, you must have noticed that the Kinect SDK is flexible enough to detect the device status this well. This will really help avoid unnecessary exceptions and application crashes.
The StausChanged
events are attached to all the elements of KinectSensorCollection
. So, you can track the status change of each and every Kinect device if there is more than one device connected. When the StatusChanged
event is fired, it invokes the event handler with StatusChangedEventArgs
, which has associated with the sensor. The following image shows the sensor property of the Kinect StatusChangedEventArgs
class within the event handler that is raised by the StatusChanged
event:

Resuming your application automatically
You have also seen that, during the lifespan of a Kinect application the status of the sensor can change. You can start the sensor only when it's in the connected state and you need to call the Start()
method explicitly to start it. We can take advantage of the StatusChanged
event to start the sensor and resume our application automatically when it is connected. You can save the state of your application when the status is Disconnected
or NotPowered
and can resume it automatically once it is connected by starting the sensor and reloading your application state. This is shown in the following diagram:

Building KinectStatusNotifier
In this section, we are going to learn how to build a notification application named KinectStatusNotifier that uses the Kinect sensor and shows the sensor status in the system tray. KinectStatusNotifier will pop up a notification icon in the system tray whenever there is a change in the sensor status (refer to the following screenshot).

If you want to show some custom messages with the status change, you can also explicitly call KinectStatusNotifier to notify of a status change in the system tray, as shown in the following screenshot:

We will start this application from scratch with a new ClassLibrary
project, as follows:
- Start a new instance of Visual Studio.
- Create a new project by navigating to File | New Project.
- Select the Visual C# template and pick the Class Library option from the template options.
- Name the library
KinectStatusNotifier
, as shown in the following image. Click on OK to create the project.Note
NotifyIcon
is a class in theSystem.Windows.Forms
namespace and can be used to invoke the default notification from the system tray. By default, the WPF application does not haveNotifyIcon
, so we are going to create a wrapper aroundSystem.Windows.Forms.NotifyIcon
so that we can easily invoke it from any application.Perform the following steps to set up our projects:
- Remove the exiting classes from the KinectStatusNotifier project and add a new class by right-clicking on Project | Add New Item | Class. Give it the name
StatusNotifier
and click on OK. - Add a reference to
System.Windows.Forms
andSystem.Drawing
to theKinectStatusNotifier
project.
Once we have the project set up, the first thing we need to do is to create an instance of NotifyIcon
, as follows:
private NotifyIcon kinectNotifier = new NotifyIcon();.
KinectNotifier
now holds the reference to NotifyIcon
and can be invoked by a status change of the sensor. Hence, we need the reference to KinectSensorCollection
in the KinectStatusNotifier project.
Add a property of type KinectSensorCollection
, as follows:
private KinectSensorCollection sensorsValue; public KinectSensorCollection Sensors { get { return this.sensorsValue; } set { this.sensorsValue = value; this.AutoNotification = true; } }
Sensors
is a public property of the StatusNotifier
class that holds the reference to KinectSensorCollection
that is passed from the calling application. If you have noticed, we have an additional AutoNotification
property, which is by default set to true
; however, if you look inside the definition of this property, you will find this:
private bool autoNotificationValue; public bool AutoNotification { get { return this.autoNotificationValue; } set { this.autoNotificationValue = value; if (value) { this.Sensors.StatusChanged += this.Sensors_StatusChanged; } else { this.sensors.StatusChanged -= this.Sensors_StatusChanged; } } }
We are subscribing to the StatusChanged
event handler only when AutoNotification
is set to true
. This will give you a choice between using the automatic notification with status change and not using it, as shown in the following screenshot:

The StatusNotifer
class has a few more properties for the notification title, message, and sensor status, as shown in the preceding class diagram. The StatusNotifer
class has a defined enumeration called StatusType
, which is either the information or a warning. The NotifierMessage
and NotifierTitle
properties are set in the Sensor_StatusChanged
event handler, which was registered from the AutoNotification
property as follows:
protected void Sensors_StatusChanged(object sender, StatusChangedEventArgs e)
{
this.SensorStatus = e.Status;
this.NotifierTitle = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
this.NotifierMessage = string.Format("{0}\n{1}", this.SensorStatus.ToString(), e.Sensor.DeviceConnectionId);
this.StatusType = StatusType.Information;
this.NotifyStatus();
}
As you can see in the preceding code, the NotifierTitle
property is set to the name of the application, and the NotifierMessage
property is set to SensorStatus
and DeviceConnectionId
. Finally, the call to the NotifyStatus()
method sets the StatusNotifier
property to the kinectNotifier
instance of the NotifyIcon
class and invokes the ShowBallonTip()
method to notify an icon on the system tray. The NotifyStatus
class is shown in the following code snippet:
public void NotifyStatus()
{
this.kinectNotifier.Icon = new Icon(this.GetIcon());
this.kinectNotifier.Text = string.Format("Device Status : {0}",this.SensorStatus.ToString());
this.kinectNotifier.Visible = true;
this.kinectNotifier.ShowBalloonTip(3000, this.NotifierTitle, this.NotifierMessage, this.StatusType == StatusType.Information ? ToolTipIcon.Info : ToolTipIcon.Warning);
}
Using KinectStatusNotifier
KinectStatusNotifier
is not a self-executable; it generates a KinectStatusNotifier.dll
assembly that can be used with a Kinect application. Let's integrate this to our previously built Kinect Info Box application and see how it works. This can be done simply by performing the following steps:
- Add the
KinectStatusNotifier.dll
assembly as a reference assembly to the Kinect Info Box application from the Add References window. - Add the following namespace in the application:
using KinectStatusNotifier;
- Instantiate a new object for the
StatusNotifier
class, as follows:private StatusNotifier notifier = new StatusNotifier();
- Assign the
KinectSensor.KinectSensors
collection as a reference tonotifer.Sensors
, as follows:this.notifier.Sensors = KinectSensor.KinectSensors;
That's all! The StatusNotifer
class will take care of the rest. Whenever there is a change in the status of the sensor, you can see a notification with the current status in the System Tray icon.
Note
You can set the value of AutoNotification
to false
, which will stop the automatic notification in the system tray at the StatusNotifer
class level and invoke the NotifyIcon
class explicitly when there is a status change. It will do this by handling the StatusChanged
event handler in your application itself. You can also handle it from both places, while you can change the status in the tray icon from a single place.
To test the application out and see how the application and the sensor work together, first run the Kinect Info Box application and then switch off the power to the sensor and switch it back on. As shown in the following screenshot, you will able to see exactly three different changes in sensor status in the system tray notification:
