Mobile Sensor API Version 1.2

javax.microedition.sensor
Interface SensorConnection

All Superinterfaces:
javax.microedition.io.Connection

public interface SensorConnection
extends javax.microedition.io.Connection

The SensorConnection is an abstraction of an actual sensor. It provides the functionality to retrieve data from a sensor.

A sensor can be widely understood as any measurement data source. It provides a direct output to the physical stimuli such as heat, light, sound, pressure, magnetism, or motion. Alternatively, a sensor can be a virtual data source that supplies data, which is collected from various sources and manipulated.

Synchronous and asynchronous data retrieval modes

The main task of a SensorConnection is to enable data retrieval from a sensor. The application can retrieve data either synchronously or asynchronously. Synchronous mode means that the application is iteratively calling getData(int)/ getData(int, long, boolean, boolean, boolean) methods. Asynchronous mode requires the application to implement the DataListener interface. When the application implements this interface and registers itself with the setDataListener() method, it starts to receive DataListener.dataReceived() notifications.

Both synchronous and asynchronous retrieval deliver the data encapsulated in Data objects. The content of Data objects can be configured with parameters of getData()/setDataListener() methods. The application is able to configure the buffering of the data, and presence of the timestamp, the uncertainty, and the validity. Buffering can be controlled with a buffer size parameter, or a buffering period, or both.

Data buffering with a larger buffer size is recommended if the application is performance-critical. Buffering has also a favorable effect of easing garbage collection. If the sampling rate is, for example, 1000 Hz, by setting the size of the buffer to 100, only 10 Data objects per second are created. This is far easier to handle than 1000 objects per second. Omitting either the timestamp, or the uncertainty, or the validity, or all of these can also optimize the performance. The maximum buffer size MUST be 256 in minimum for all the sensors in all the devices. The maximum buffer size of this sensor can be obtained with the method SensorInfo.getMaxBufferSize(). The data retrieval methods will throw an IllegalArgumentException if the desired buffer size exceeds defined maximum.

States

The SensorConnection has three possible states:

  1. STATE_OPENED
  2. STATE_LISTENING
  3. STATE_CLOSED

Right after the SensorConnection is opened, it is in the STATE_OPENED state. When the DataListener is registered, the state moves from STATE_OPENED to STATE_LISTENING. If the DataListener is removed, the SensorConnection returns back to the STATE_OPENED state. After the close() method is called, the SensorConnection is in its final state, STATE_CLOSED. There is no longer any way back to the other states. No data MUST be provided for the application after the connection is closed. The states of SensorConnection are presented in the figure below.

The state machine of the
 SensorConnection

Figure 3: The state machine of SensorConnection class

Calling some methods may fail if the SensorConnection is not in an appropriate state for the method. In the table below states and corresponding illegal methods are depicted:

State Illegal methods
STATE_OPENED -
STATE_LISTENING getData() throws IllegalStateException
STATE_CLOSED getData() throws IOException setDataListener() and removeDataListener() throw IllegalStateException

Grouping channels, dividing quantities

The SensorConnection may provide simultaneous measurements from different channels, and for clarity different measurements are stored into separate Data objects. The number of channels depends on the nature of the sensor. For example, a thermometer returns only one value representing temperature, so it has only one channel. A 3D compass returns a collection of three values each representing orientation in one particular direction; therefore it is a "three-channel" sensor.

In the case of a 3D compass having channels "heading", "pitch", and "roll", it is recommended to group these three channels to be in the same SensorConnection entity. Of course, there is a chance that the application is only interested in the "heading" values. If this is the case, the SensorConnection dedicated to the "heading" values would serve best. However, different, simultaneous modes would increase the complexity of the design and implementation and offer only small benefits. The different SensorConnection implementations should be aligned with the way the physical sensors are measuring things. If a compass is measuring heading, pitch, and roll values together in one shot, these values should be channels of one SensorConnection.

The situation changes if the measuring device is capable of measuring more than one quantity, for example, humidity and temperature. In such a case it is recommended to offer the separate SensorConnection for each quantity, and not one SensorConnection with two channels. It is implementation dependent whether separate SensorConnection objects to the same device can be opened simultaneously.

Addressing

The SensorConnection is extended from a General Connection Framework's Connection to be aligned with a widely accepted convention and to ease the application wakeup based on the usage of the MIDP PushRegistry.

EBNF Syntax for Connector.open() URL

A new URL scheme is defined for sensors, and it conforms to the URL format described in RFC 2396. When the connection to a sensor is opened using Connector.open(), the URL must conform to the EBNF syntax specified below. If the URL passed to Connector.open() defines the "sensor:" scheme but is not valid according to the sensor URL scheme defined here, an IllegalArgumentException is thrown. Identical sensors, which have the same model information, should provide location information to enable to distinguish sensors from each other. Quantity is the only mandatory parameter in the URL. Sensor examples and corresponding quantities can be found in the table of Appendix A "Finding sensors".

<sensor_url> ::= "sensor:"<sensor_id>
<sensor_id> ::= <quantity>[<contextType>][<model>][<location>]
<quantity> ::= ("temperature"|"acceleration"|...)
<contextType> ::= <separator>"contextType="("ambient"|"device"|"user"|"vehicle")
<model> ::= <separator>"model="<model_id>
<model_id> ::= <alphanum>*
<location> ::= <separator>"location="<location_id>
<location_id> ::= <alphanum>*
<separator> ::= ";"

Examples of sensor URLs for Connector.open():

EBNF Syntax for the PushRegistry URL

In MIDP 2.0 the PushRegistry provides the push mechanism to start the MIDlet based on some specific impulse. More information about automatic launch can be found in the Appendix C.

When registering sensors to the MIDP PushRegistry, the URL must conform to the EBNF syntax specified below. When the PushRegistry.registerConnection() is called and the connection URL parameter specifies "sensor:" scheme but does not conform to this syntax, an IllegalArgumentException is thrown.

<push_sensor_url> ::= <sensor_url>[<params>]
<params> ::= "?"<channel_list>
<channel_list> ::= <channel>[<separator2><channel>]*
<channel> ::= "channel="<channel_id><separator2><condition_list>
<channel_id> ::= <alphanum>+
<condition_list> ::= <condition>[<separator2><condition>]*
<condition> ::= (<limit>|<range>)
<limit> ::= "limit="<double><separator2>"op="("eq"|"lt"|"le"|"ge"|"gt")
<range> ::="lowerLimit="<double><separator2> "lowerOp="("ge"|"gt")<separator2> "upperLimit="<double><separator2> "upperOp="("le"|"lt")
<separator2> ::= "&"
<double> ::= "-"?(<integer>|<decimal>)
<integer> ::= <nonzero-digit><digit>*
<decimal> ::= <integer>"."<digit>+
<digit> ::= "0"|<nonzero-digit>
<nonzero-digit> ::= "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"

Examples of the sensor URLs for the PushRegistry:

Setting conditions with a URL is analogous to specifying them using the Condition classes. An ObjectCondition or custom Condition objects cannot be used. The application is launched when any of the conditions set in the URL are met.


Field Summary
static int STATE_CLOSED
          The SensorConnection state after the method close() is called; the end state.
static int STATE_LISTENING
          The SensorConnection state when the asynchronous data retrieval mode is on.
static int STATE_OPENED
          The SensorConnection state after successful instantiation of the SensorConnection.
 
Method Summary
 Channel getChannel(ChannelInfo channelInfo)
          This method returns the Channel object that maintains Condition objects attached to the corresponding channel of the sensor.
 Data[] getData(int bufferSize)
          Retrieves data in the synchronous mode.
 Data[] getData(int bufferSize, long bufferingPeriod, boolean isTimestampIncluded, boolean isUncertaintyIncluded, boolean isValidityIncluded)
          Retrieves data in the synchronous mode.
 int[] getErrorCodes()
          The method will return all the sensor specific error codes that the sensor is capable of reporting.
 java.lang.String getErrorText(int errorCode)
          The method will return a sensor specific error description based on the error code given as a parameter.
 SensorInfo getSensorInfo()
          Returns SensorInfo that contains information about the sensor
 int getState()
          Returns the current state of the SensorConnection.
 void removeDataListener()
          Removes the DataListener registered to this SensorConnection.
 void setDataListener(DataListener listener, int bufferSize)
          Registers a DataListener to receive collected data asynchronously.
 void setDataListener(DataListener listener, int bufferSize, long bufferingPeriod, boolean isTimestampIncluded, boolean isUncertaintyIncluded, boolean isValidityIncluded)
          Registers a DataListener to receive collected data asynchronously.
 
Methods inherited from interface javax.microedition.io.Connection
close
 

Field Detail

STATE_OPENED

static final int STATE_OPENED

The SensorConnection state after successful instantiation of the SensorConnection. The connection is open and data can be retrieved.

See Also:
Constant Field Values

STATE_LISTENING

static final int STATE_LISTENING

The SensorConnection state when the asynchronous data retrieval mode is on. The application is listening to DataListener.dataReceived() notifications.

See Also:
Constant Field Values

STATE_CLOSED

static final int STATE_CLOSED

The SensorConnection state after the method close() is called; the end state.

See Also:
Constant Field Values
Method Detail

getChannel

Channel getChannel(ChannelInfo channelInfo)

This method returns the Channel object that maintains Condition objects attached to the corresponding channel of the sensor. The channelInfo parameter is compared using instance equality and therefore needs to be an instance previously returned from SensorInfo.getChannelInfos() method of the SensorInfo object corresponding to this sensor.

Parameters:
channelInfo - the ChannelInfo object which defines the channel
Returns:
Channel
Throws:
java.lang.IllegalArgumentException - if SensorInfo does not contain matching ChannelInfo object
java.lang.NullPointerException - if the channelInfo is null

getData

Data[] getData(int bufferSize)
               throws java.io.IOException

Retrieves data in the synchronous mode. The collection of the data is started when the method is called. When this getData() method is used, timestamp, validity, and uncertainty values are not included in Data objects. The method will return when the size of the data value buffer equals the bufferSize parameter. The bufferSize parameter defines the number of samples inside each Data object.

Parameters:
bufferSize - the size of the data value buffer of the Data object - value must be > 0
Returns:
the collected data of all the channels of this sensor. There will be as many Data objects returned as there are channels.
Throws:
java.lang.IllegalArgumentException - if bufferSize < 1 or if bufferSize exceeds the maximum size of the buffer
java.io.IOException - if the state is STATE_CLOSED or if I/O operations on the SensorConnection are being blocked, which can happen, for example, when a sensor becomes unavailable or when the SensorConnection is closed with the close() method during a call to this method. The IOException MUST be thrown right away after the sensor becomes unavailable.
java.lang.IllegalStateException - if the state is STATE_LISTENING

getData

Data[] getData(int bufferSize,
               long bufferingPeriod,
               boolean isTimestampIncluded,
               boolean isUncertaintyIncluded,
               boolean isValidityIncluded)
               throws java.io.IOException

Retrieves data in the synchronous mode. The data is collected from the sensor according to the given parameters. The collection of the data is started when the method is called. If data cannot be retrieved then a zero-length Data array is returned. This can happen, for example, when the bufferingPeriod is very small and the measurement is slow.

The parameters of the method have an effect on retrieved Data objects. The size of the data value buffer is defined and/or the time period to buffer the data and whether the additional information, such as timestamps, uncertainties, and validities, should be included. The data value buffer size is controlled with both parameters bufferSize and bufferingPeriod. A negative value indicates that the parameter is left undefined. The bufferSize and bufferingPeriod have the following relationship:

Parameters:
bufferSize - the size of the buffer of the data values, bufferSize < 1 means the size is left undefined
bufferingPeriod - the time to buffer values - given in milliseconds, bufferingPeriod < 1 means the period is left undefined
isTimestampIncluded - if true timestamps should be included in returned Data objects
isUncertaintyIncluded - if true uncertainties should be included in returned Data objects
isValidityIncluded - if true validities should be included in returned Data objects
Returns:
collected data of all the channels of this sensor. There will be as many Data objects returned as there are channels.
Throws:
java.lang.IllegalArgumentException - if the both, bufferSize and bufferingPeriod, have values less than 1, or if bufferSize exceeds the maximum size of the buffer
java.lang.IllegalStateException - if the state is STATE_LISTENING
java.io.IOException - if the state is STATE_CLOSED or if I/O operations on the SensorConnection are being blocked, which can happen, for example, when a sensor becomes unavailable or when the SensorConnection is closed with the close() method during a call to this method. The IOException MUST be thrown right away after the sensor becomes unavailable.

getErrorCodes

int[] getErrorCodes()

The method will return all the sensor specific error codes that the sensor is capable of reporting. When adding a new sensor its error codes MUST be documented if the sensor is reporting errors.

Returns:
all the valid error codes as an int array. If the sensor is not reporting errors, i.e. the property PROP_IS_REPORTING_ERRORS is not set, then a zero-length int array is returned. If the sensor reports errors, there MUST be at least one error code returned.

getErrorText

java.lang.String getErrorText(int errorCode)

The method will return a sensor specific error description based on the error code given as a parameter. The description MUST NOT be an empty string or null.

Parameters:
errorCode - the code of the error occured
Returns:
the description of the error which occured
Throws:
java.lang.IllegalArgumentException - if the given errorCode is not valid and always if the property SensorInfo.PROP_IS_REPORTING_ERRORS is not set

getSensorInfo

SensorInfo getSensorInfo()

Returns SensorInfo that contains information about the sensor

Returns:
a SensorInfo object containing information about this sensor

getState

int getState()

Returns the current state of the SensorConnection.

Returns:
the state of the SensorConnection; possible return values are:

removeDataListener

void removeDataListener()

Removes the DataListener registered to this SensorConnection. The DataListener stops getting dataReceived() notifications. The state changes from STATE_LISTENING to STATE_OPENED, and data can now be retrieved synchronously using getData() methods. If there is no DataListener and the state is STATE_OPENED, the method returns silently.

Throws:
java.lang.IllegalStateException - if this SensorConnection is already closed

setDataListener

void setDataListener(DataListener listener,
                     int bufferSize)

Registers a DataListener to receive collected data asynchronously. The registered DataListener receives data within sequential dataReceived() notifications. The notification is sent when the number of collected data values equals a set size of the buffer. To quit receiving notifications the method removeDataListener() has to be called. Data MUST NOT be sent after the sensor becomes unavailable.

If there is a DataListener already set, it will be replaced with the listener given as a parameter. When this setDataListener() method is used, timestamp, validity, and uncertainty values are not included in the Data objects.

Parameters:
listener - DataListener to be registered
bufferSize - size of the buffer, value must be > 0
Throws:
java.lang.NullPointerException - if the listener is null
java.lang.IllegalArgumentException - if the bufferSize < 1, or if bufferSize exceeds the maximum size of the buffer
java.lang.IllegalStateException - if this SensorConnection is already closed

setDataListener

void setDataListener(DataListener listener,
                     int bufferSize,
                     long bufferingPeriod,
                     boolean isTimestampIncluded,
                     boolean isUncertaintyIncluded,
                     boolean isValidityIncluded)

Registers a DataListener to receive collected data asynchronously. The registered DataListener receives data within sequential dataReceived() notifications. If there is a DataListener already set, it will be replaced with the given listener parameter. To quit receiving notifications the method removeDataListener() has to be called.

The parameters of the method have an effect on retrieved Data objects. The size of the data value buffer is defined and/or the time period to buffer the data and whether the additional information, such as timestamps, uncertainties, and validities, should be included. The data value buffer size is controlled with both parameters bufferSize and bufferingPeriod. A negative value indicates that the parameter is left undefined. The bufferSize and bufferingPeriod have the following relationship:

Parameters:
listener - the listener to be registered
bufferSize - the size of the buffer of the data values, bufferSize < 1 means the size is left undefined
bufferingPeriod - the time in milliseconds to buffer values inside one Data object. bufferingPeriod < 1 means the period is left undefined.
isTimestampIncluded - if true timestamps should be included in returned Data objects
isUncertaintyIncluded - if true uncertainties should be included in returned Data objects
isValidityIncluded - if true validities should be included in returned Data objects
Throws:
java.lang.NullPointerException - if the listener is null
java.lang.IllegalArgumentException - if the bufferSize and the bufferingPeriod both are < 1 or if bufferSize exceeds the maximum size of the buffer
java.lang.IllegalStateException - if this SensorConnection is already closed

Mobile Sensor API Version 1.2

Copyright © 2005-2008 Nokia Corporation. All Rights Reserved.
Java is a trademark of Sun Microsystems, Inc.