Most systems you e likely to encounter have at most one Bluetooth controller. This is represented by the singleton class javax.bluetooth.LocalDevice :
public class LocalDevice extends java.lang.Object
The static LocalDevice.getLocalDevice( ) method returns the single LocalDevice object that represents the host controller:
public static LocalDevice getLocalDevice( ) throws BluetoothStateException
This method never returns null. If the local system does not have a Bluetooth device, or if the Bluetooth hardware cannot be initialized, this method throws a BluetoothStateException, a subclass of IOException.
The LocalDevice class has a number of getter methods to query the controller and two methods for making the device discoverable (or not) and updating the devices service records.
The getBluetoothAddress( ) method returns a String containing the 6-byte Bluetooth address of the controller:
public String getBluetoothAddress( )
The address is a string of 12 hex digits, such as 000D930D11B3. This isn very nice for display to the end user, so theres also a getFriendlyName( ) method that returns a more human-legible name:
public String getFriendlyAddress( )
Example 25-1 is a simple program that uses these two methods to list information about the host system.
import javax.bluetooth.*; public class BluetoothTest { public static void main(String[] args) throws Exception { LocalDevice device = LocalDevice.getLocalDevice( ); System.out.print(device.getFriendlyName( ) + " at "); System.out.print(device.getBluetoothAddress( )); System.exit(0); } } |
Loading the Bluetooth libraries sometimes spawns a nondaemon thread, so its necessary to call System.exit( ) to force the program to quit (much the same as when using AWT classes).
Example 25-1 won run with just the standard JDK. Youll need to have a JSR 82 implementation in your classpath. For example, heres how I compile and run this program on my PowerMac G5:
$ javac -classpath .:avetanaBluetooth.jar BluetoothTest.java $ java -classpath .:avetanaBluetooth.jar BluetoothTest avetanaBluetooth version 1.3.1 Local name eliza Local address 00-0d-93-0d-11-b3 Device class 0 Possibilities array 3F License-ID 1498 eliza at 000D930D11B3
The first six lines are just random junk the particular JSR 82 implementation Im using spews. The last line is the actual output from the program. In upcoming examples, Ill omit Avetanas initialization info.
|
LocalDevices getProperty( ) method returns a named Bluetooth property:
public static String getProperty(String property)
These 10 properties are defined in all devices:
bluetooth.api.version
The version of the Java API for Bluetooth wireless technology (currently 1.0)
bluetooth.master.switch
Whether slaves and masters can exchange roles (either TRue or false)
bluetooth.sd.attr.retrievable.max
The maximum number of service attributes in each service record
bluetooth.connected.devices.max
The maximum number of simultaneously connected devices
bluetooth.l2cap.receiveMTU.max
The maximum receive MTU size in L2CAP
bluetooth.sd.trans.max
The maximum number of simultaneous service discovery transactions
bluetooth.connected.inquiry.scan
Whether inquiry scanning is allowed during connection (either true or false)
bluetooth.connected.page.scan
Whether page scanning is allowed during connection (either true or false)
bluetooth.connected.inquiry
Whether inquiry is allowed during connection (either true or false)
bluetooth.connected.page
Whether a connection can be established to a device that is already connected to another device (either TRue or false)
If this were primarily a J2SE API, each of these values might well be a separate method call. However, since space is at premium in the J2ME environments for which the Java Bluetooth API was designed, it pays to compress them all into one method. This approach is also more extensible, since particular JSR 82 implementations may define additional properties as well.
Example 25-2 is a simple program that prints the values of the 10 standard properties of the local system.
import javax.bluetooth.*; public class BluetoothProperties { public static void main(String[] args) throws Exception { LocalDevice device = LocalDevice.getLocalDevice( ); System.out.println("API version: " + device.getProperty("bluetooth.api.version")); System.out.println("bluetooth.master.switch: " + device.getProperty("bluetooth.master.switch")); System.out.println("Maximum number of service attributes: " + device.getProperty("bluetooth.sd.attr.retrievable.max")); System.out.println("Maximum number of connected devices: " + device.getProperty("bluetooth.connected.devices.max")); System.out.println("Maximum receive MTU size in L2CAP: " + device.getProperty("bluetooth.l2cap.receiveMTU.max")); System.out.println( "Maximum number of simultaneous service discovery transactions: " + device.getProperty("bluetooth.sd.trans.max")); System.out.println("Inquiry scanning allowed during connection: " + device.getProperty("bluetooth.connected.inquiry.scan")); System.out.println("Page scanning allowed during connection: " + device.getProperty("bluetooth.connected.page.scan")); System.out.println("Inquiry allowed during connection: " + device.getProperty("bluetooth.connected.inquiry")); System.out.println("Page allowed during connection: " + device.getProperty("bluetooth.connected.page")); System.exit(0); } } |
Heres the output from running this on my PowerMac G5 using the Avetana implementation:
API version: 1.0 bluetooth.master.switch: true Maximum number of service attributes: null Maximum number of connected devices: 1 Maximum receive MTU size in L2CAP: null Maximum number of simultaneous service discovery transactions: 1 Inquiry scanning allowed during connection: false Page scanning allowed during connection: false Inquiry allowed during connection: false Page allowed during connection: false
It looks like the Avetana implementation fails to recognize the bluetooth.sd.attr.retrievable.max and bluetooth.l2cap.receiveMTU.max properties. It recognizes the rest.
The getdeviceClass( ) method tells you what kind of Bluetooth device the program is running on:
public DeviceClass getDeviceClass( )
The information is encapsulated in a DeviceClass object. This class has three getter methods to describe the major class, minor class, and service classes:
public int getMajorDeviceClass( ) public int getMinorDeviceClass( ) public int getServiceClasses( )
These methods all return ints. The values of these ints are defined by the Bluetooth specification. Table 25-1 listed the currently defined major device classes, but more classes may be added in the future. Each device has exactly one major and one minor class. However, it can have several service classes, in which case the constants for each such class are combined with the bitwise or operator.
Bluetooth devices may be discoverable. A discoverable device can be paired with another Bluetooth device so that the two can exchange data. For security reasons, devices often have personal identification numbers (PINs) that have to be entered from the discovering device in order to connect to the discovered device. This makes it harder for an unauthorized person to extract information from your Bluetooth devices.
The geTDiscoverable( ) method returns an int indicating whether and how a device is discoverable:
public int getDiscoverable( )
The return value can be:
DiscoveryAgent.NOT_DISCOVERABLE
Device cannot be discovered by a remote device
DiscoveryAgent.GIAC
Device can be discovered by any remote device
DiscoveryAgent.LIAC
Device can be discovered by other LIAC devices for a limited period of time (more on LIAC in a moment)
Some devices may allow you to make them discoverable or not discoverable by passing the appropriate mode to the setDiscoverable( ) method:
public boolean setDiscoverable(int mode) throws BluetoothStateException
This method returns TRue if the device state was set as requested or false if it wasn . It throws an IllegalArgumentException if you pass an illegal state. It throws a BluetoothStrateException if the device is in a state that cannot be changed right now.