The com.oracle.deviceaccess.generic
package contains interfaces and classes for controlling devices using generic I/O operations.
The generic device API allows for accessing peripheral devices when there are no more specific standard Java APIs, such as I2CDevice
, SPIDevice
, GPIOPin
or GPIOPort
. This API offers three primary interfaces to encapsulate these devices:
This interface encapsulates device control operations and event listener registration. A device may implement this sole interface if it does not support any read and write operations.
This interface encapsulates device control operations and event listener registration as inherited from GenericBufferIODevice
as well as byte buffer read and write operations.
This interface encapsulates device control operations and event listener registration as inherited from GenericBufferIODevice
as well as stream-based read and write operations.
In order to access a device using its generic interface, an application should first open and obtain a GenericDevice
instance for the device using its numerical ID, name, type (interface) and properties.
This is an example of using its ID.
GenericDevice device = (GenericDevice) PeripheralManager.open(17);
This is an example of using its name and interface.
GenericStreamIODevice device = (GenericDevice) PeripheralManager.open("STORAGE", GenericStreamIODevice.class, null);
Once the peripheral is opened, the application can set and get its controls, as well as read and write data using methods of the GenericDevice
, GenericBufferIODevice
or GenericStreamIODevice
interfaces.
device.read(buffer, 0, buffer.length);
When completed, the application should call the GenericDevice.close()
method to release the device.
device.close();
Example 6-1 and Example 6-2 show how to use the generic API to communicate with Real Time Clock device and an audio capture microphone, which may be accessible over USB.
Example 6-1 Creating an Alarm using the Generic APIs
import com.oracle.deviceaccess.PeripheralException; import com.oracle.deviceaccess.PeripheralManager; import com.oracle.deviceaccess.generic.GenericDevice; import com.oracle.deviceaccess.generic.GenericEvent; import com.oracle.deviceaccess.generic.GenericEventListener; import java.io.IOException; public class GenericAlarm { public static final int EVT_ALARM = 0; public static final int SECONDS = 0; public static final int SEC_ALARM = 1; public static final int MINUTES = 2; public static final int MIN_ALARM = 3; public static final int HR_ALARM = 4; public static final int HOURS = 5; public static final int ALARM_ENABLED = 6; private GenericDevice rtc = null; // Sets the daily alarm for after some delay public void setAlarm(byte delaySeconds, byte delayMinutes, byte delayHours) throws IOException, PeripheralException { rtc = (GenericDevice) PeripheralManager.open("RTC", GenericDevice.class, (String[]) null); byte currentSeconds = ((Byte) rtc.getControl(SECONDS)).byteValue(); byte currentMinutes = ((Byte) rtc.getControl(MINUTES)).byteValue(); byte currentHours = ((Byte) rtc.getControl(HOURS)).byteValue(); byte i = (byte) ((currentSeconds + delaySeconds) % 60); byte j = (byte) ((currentSeconds + delaySeconds) / 60); rtc.setControl(SEC_ALARM, new Byte(i)); i = (byte) ((currentMinutes + delayMinutes + j) % 60); j = (byte) ((currentMinutes + delayMinutes + j) / 60); rtc.setControl(MIN_ALARM, new Byte(i)); i = (byte) ((currentHours + delayHours + j) % 24); rtc.setControl(HR_ALARM, new Byte(i)); rtc.setEventListener(EVT_ALARM, new GenericEventListener() { public void eventDispatched(GenericEvent event) { GenericDevice rtc = (GenericDevice) event.getPeripheral(); // Notify application of alarm } }); // Enable alarm. rtc.setControl(ALARM_ENABLED, Boolean.TRUE); } public void close() { try { rtc.close(); } catch (IOException ex) { } } }
Example 6-2 An Audio Capture Using the Generic APIs
import com.oracle.deviceaccess.PeripheralException; import com.oracle.deviceaccess.PeripheralManager; import com.oracle.deviceaccess.PeripheralNotAvailableException; import com.oracle.deviceaccess.generic.GenericBufferIODevice; import com.oracle.deviceaccess.generic.GenericDevice; import com.oracle.deviceaccess.generic.GenericEvent; import com.oracle.deviceaccess.generic.GenericEventListener; import java.io.IOException; public class GenericAudioCapture { public static final int EVT_VOLUME_CHANGED = 0; public static final int MIC_VOLUME = 0; public static final int MIC_SAMPLE_RATE = 1; public static final int MIC_AUTOMATIC_GAIN = 2; public static final int MIC_MUTE = 3; public void audioCapture(byte[] buffer, float sampleRate, boolean agc) throws IOException, PeripheralException { GenericBufferIODevice mic = null; try { mic = (GenericBufferIODevice) PeripheralManager .open("MICROPHONE", GenericBufferIODevice.class, (String[]) null); mic.setControl(MIC_SAMPLE_RATE, new Float(sampleRate)); mic.setControl(MIC_AUTOMATIC_GAIN, agc ? Boolean.TRUE : Boolean.FALSE); mic.setControl(MIC_MUTE, Boolean.FALSE); mic.setEventListener(EVT_VOLUME_CHANGED, new GenericEventListener() { public void eventDispatched(GenericEvent event) { GenericDevice mic = (GenericDevice) event.getPeripheral(); try { float currentVolume = ((Float) mic.getControl(MIC_VOLUME)).floatValue(); // ... } catch (IOException ex) { ex.printStackTrace(); } catch (PeripheralNotAvailableException ex) { ex.printStackTrace(); } } }); mic.read(buffer, 0, buffer.length); } finally { if (mic != null) { mic.close(); } } } }
Generic devices are opened by invoking one of the com.oracle.deviceaccess.PeripheralManager.open()
methods. The com.oracle.deviceaccess.generic
permission allows access to be granted to generic devices as a whole. This permission must be requested in the JAD file under MIDlet-Permissions
or MIDlet-Permissions-Opt
, and the application must be digitally signed by a trusted authority to gain access to the APIs. Alternatively, the permission may be allowed for all applications in the untrusted
domain of the security policy file (policy.txt
).
The GenericBufferIODevice
interface defines generic methods for accessing and controlling peripheral devices using read and write operations.
A platform implementer may allow access and control of peripheral devices for which there exist no other more specific APIs through this interface.
The GenericBufferIODevice
interface contains three methods.
int read(byte[] rxBuf, int rxOff, int rxLen) throws java.io.IOException, PeripheralNotAvailableException
This method reads up to rxLen
bytes of data from this device into an array of bytes. Note that the availability of new input data may be notified through an GenericEvent
with ID GenericEvent.INPUT_DATA_AVAILABLE
.
int read(int skip, byte[] rxBuf, int rxOff, int rxLen) throws java.io.IOException, PeripheralNotAvailableException
This method reads up to rxLen
bytes of data from this device into an array of bytes skipping the first skip bytes read. Note that the availability of new input data may be notified through an GenericEvent
with ID GenericEvent.INPUT_DATA_AVAILABLE
.
void write(byte[] txBuf, int txOff, int txLen) throws java.io.IOException, PeripheralNotAvailableException
This method writes to this device txLen
bytes from buffer txBuf
. Note that an empty output buffer condition may be notified through an GenericEvent
with ID GenericEvent.OUTPUT_BUFFER_EMPTY
.
The GenericDevice
interface defines methods for setting and getting peripheral device-specific configuration and access (I/O) controls as well as registering event listeners.
An application can use this interface to set and get configuration and access (I/O) controls. A control is identified by a numerical ID and can be set or gotten using the setControl(int, java.lang.Object)
and getControl(int)
methods. Controls can be used to configured a peripheral device a well as performing basic input/output operations. The list of controls supported by a peripheral device is peripheral-device-specific.
An application can also register an GenericEventListener
instance to monitor native events of the designated type fired by the peripheral device. To register a GenericEventListener
instance, the application must call the setEventListener(int, GenericEventListener)
method. The registered listener can later on be removed by calling the same method with a null listener parameter. Asynchronous notification may not be supported by all devices. An attempt to set a listener on a device which does not supports it will result in an InvalidOperationException
being thrown.
A platform implementer may allow through this interface access and control of peripheral devices which do not require byte stream or buffer I/O (read, write) and for which there exist no other more specific API.
The GenericDevice
interface consists of three methods:
void setControl(int id, java.lang.Object value) throws java.io.IOException, PeripheralNotAvailableException
This method sets the value of the specified control.
java.lang.Object getControl(int id) throws java.io.IOException, PeripheralNotAvailableException
This method returns the value of the specified control.
void setEventListener(int eventId, GenericEventListener listener) throws java.io.IOException, PeripheralNotAvailableException
This method registers a GenericEventListener
instance to monitor native events of the designated type fired by the peripheral device associated to this GenericDevice
object. While the listener can be triggered by hardware interrupts, there are no real-time guarantees of when the listener will be called. A list of event type IDs is defined in GenericEvent
. This list can be extended with peripheral-specific IDs. If listener is null then listener previously registered for the specified event type will be removed. Only one listener can be registered at a particular time for a particular event type.
The GenericEventListener
interface defines methods for being notified of events fired by peripheral devices that implement the GenericDevice
interface. A GenericEventListener
can be registered using the GenericDevice.setEventListener(int, GenericEventListener)
method.
The GenericEventListener
interface consists of one method:
The GenericStreamIODevice
interface defines generic methods for accessing and controlling peripheral devices capable of working with input and output streams. A platform implementer may allow access and control of peripheral devices for which there exist no other more specific API through this interface.
The GenericStreamIODevice
interface consists of two methods:
java.io.InputStream getInputStream() throws java.io.IOException, PeripheralNotAvailableException
This method returns an input stream to this device. The same InputStream
instance is returned upon subsequent calls. Note that if this device's input stream has been previously closed, this method returns that same closed input stream without attempting to re-open it. The availability of new input data may be notified through an GenericEvent
using the ID GenericEvent.INPUT_DATA_AVAILABLE
.
java.io.OutputStream getOutputStream() throws java.io.IOException, PeripheralNotAvailableException
This method returns an output stream to this device. The same OutputStream
instance is returned upon subsequent calls. Note that if this device's output stream has been previously closed, this method returns that same closed output stream without attempting to re-open it. An empty output buffer condition may be notified through an GenericEvent
with the ID GenericEvent.OUTPUT_BUFFER_EMPTY
.
void close() throws java.io.IOException
This method closes and releases the underlying peripheral device, making it available to other applications. Once released, subsequent operations on that very same Peripheral
instance will throw a PeripheralNotAvailableException
. This method has no effects if the peripheral device has already been closed. Note that closing a GenericStreamIODevice
will also close the device's InputStream
and OutputStream
.
The GenericEvent
class encapsulates events fired by peripherals that implement the GenericDevice
interface.
The GenericEvent
interface consists of three constants:
public static final int INPUT_DATA_AVAILABLE
This constant is an event ID indicating that input data is available for reading.
public static final int INPUT_BUFFER_OVERRUN
This constant is an event ID indicating an input buffer overrun.
public static final int OUTPUT_BUFFER_EMPTY
This constant is an event ID indicating that the output buffer is empty and that additional data may be written.
The GenericEvent
interface consists of two constructors and one method:
public GenericEvent(GenericDevice device, int id)
This constructor creates a new GenericEvent
with the specified value. The event is then time-stamped with the current time.
public GenericEvent(GenericDevice device, int id, long timeStamp, int timeStampMicros)
This constructor creates a new GenericEvent
with the specified value and timestamp.
This method returns this event ID.