Tuesday, November 6, 2007

Search other bluetooth from desktop/PC

I tried to find information about developing desktop applications with Bluetooth support using Java but it seems that most of the articles are concentrated in mobile J2ME implementations. Now that I wanted to develop desktop bluetooth application I thought that I’d write down how I managed to do so. Read on, if you are interested…
Step 1. Find Bluetooth Stack Implementation for J2SE
There aren’t many JSR-82 implementations available for the desktop environment. Most of them are commercial but I was able to find the open source version from http://www.javabluetooth.org/. So the first thing was to download the source code and try to compile it. It wouldn’t compile as it depended on the Java Communications API (javax.comm.*). After I had downloaded the comm library I added comm.jar to my class path and I was able to compile the JavaBluetooth library. You can download the compiled binary here.
But… It turned out that JavaBluetooth library only supports Bluetooth devices with serial connection and thus it didn’t work with my laptop that has a built-in Bluetooth adapter.
This led me to another great site, http://www.javabluetooth.com/, which has a small list of Java Bluetooth SDKs and it included a library called BlueCove. This library works only on Windows platform but it will do for now as there aren’t other free options to choose from.
Step 2. Hello Bluetooth World
Next thing was to try it out by coding a simple application that would sniff any nearby bluetooth devices using the laptops built-in bluetooth adapter. This was easier then I thought.
You have to create class that will implement DiscoveryListener interface and the use DiscoveryAgent to search for devices. You can get the discovery agent from LocalDevice object as seen in the following code sample:


public class BluetoothBrowser
implements DiscoveryListener {

private LocalDevice localDevice;
private DiscoveryAgent agent;

/** Creates a new instance of BluetoothBrowser */
public BluetoothBrowser()
throws BluetoothStateException {
localDevice = LocalDevice.getLocalDevice();
agent = localDevice.getDiscoveryAgent();
}

/** Start inquiry */
public void inquiry()
throws BluetoothStateException {
agent.startInquiry(DiscoveryAgent.GIAC, this);
}

...implementations for DiscoveryListener...

Full Source Code of this example
This program contains 5 *.java files, such as:
1. PresenceJFrame.java
2. Application.java
3. Controller.java
4. BluetoothBrowser.java
5. Log.java

Those are full source code of file above:
PresenceJFrame.java

/*
* PresenceJFrame.java
*
* Created on 8. heinäkuuta 2007, 11:04
*/

package com.didiksoft.presence;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
*
* @author didiksoft
*/
public class PresenceJFrame extends javax.swing.JFrame {

private Controller controller;

/** Creates new form PresenceJFrame */
public PresenceJFrame() {
initComponents();
this.controller = Controller.getInstance();
}

/** Add text to the text area */
public void addText(String text) {
logTextArea.setText(logTextArea.getText() + text + "\r\n");
logTextArea.repaint();
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// =editor-fold defaultstate="collapsed" desc=" Generated Code "=//GEN-BEGIN:initComponents
private void initComponents() {

jScrollPane1 = new javax.swing.JScrollPane();
logTextArea = new javax.swing.JTextArea();
jButton1 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Bluetooth example");

logTextArea.setColumns(20);
logTextArea.setRows(5);
jScrollPane1.setViewportView(logTextArea);

jButton1.setText("Search nearby devices");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
searchDevices(evt);
}
});

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 291, Short.MAX_VALUE)
.addComponent(jButton1))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 186, Short.MAX_VALUE)
.addContainerGap())
);

pack();
}// =/editor-fold=//GEN-END:initComponents

private void searchDevices(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchDevices
controller.searchDevices();
}//GEN-LAST:event_searchDevices

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new PresenceJFrame().setVisible(true);
}
});
}

// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextArea logTextArea;
// End of variables declaration//GEN-END:variables

}


2. Application.java

/*
* __NAME__.java
*
* Copyright (C) 2007 didiksoft
* http://java-vb.blogspot.com
*
*/

package com.didiksoft.presence;

import javax.swing.UIManager;


/**
*
* @author Didik Rawandi (uchiha_didik@yahoo.com)
*/
public class Application {

private static Controller controller;

/** Creates a new instance of __NAME__ */
private Application() {
}

public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
//UIManager.setLookAndFeel( new com.jgoodies.looks.plastic.PlasticXPLookAndFeel() );
} catch(Exception ex) {
ex.printStackTrace();
}
controller = Controller.getInstance();
controller.start();
}
});


}

}

3. Controller.java

/*
* Controller.java
*
* Copyright (C) 2007 didiksoft
* http://java-vb.blogspot.com
*
*/

package com.didiksoft.presence;

import com.didiksoft.bluetooth.BluetoothBrowser;
import com.didiksoft.logging.Log;

/**
*
* @author Didik Rawandi (uchiha_didik@yahoo.com)
*/
public class Controller {

private static Controller instance;
private static PresenceJFrame mainFrame;

/** Creates a new instance of Controller */
private Controller() {
}

public static Controller getInstance() {
if(instance==null) {
instance = new Controller();
mainFrame = new PresenceJFrame();
}
return instance;
}

public void start() {
mainFrame.setVisible(true);
}

public void searchDevices() {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Log.add("Start discovery");
Thread.yield();
try {
BluetoothBrowser browser = new BluetoothBrowser();
//browser.inquiry();
Thread.yield();
Thread.sleep(15000);
} catch(Exception ex) {
Log.error("Error in main: " + ex);
}
Log.add("Discovery end");
Thread.yield();
}
});

}

public void addLogText(String text) {
mainFrame.addText(text);
}

}

4. BluetoothBrowser.java

/*
* BluetoothBrowser.java
*
* Copyright (C) 2007 didiksoft
* http://java-vb.blogspot.com
*
*/

package com.didiksoft.bluetooth;

import com.didiksoft.logging.Log;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;

/**
*
* @author Didik Rawandi (uchiha_didik@yahoo.com)
*/
public class BluetoothBrowser implements DiscoveryListener {

private LocalDevice localDevice;
private DiscoveryAgent agent;

/** Creates a new instance of BluetoothBrowser */
public BluetoothBrowser() throws BluetoothStateException {

System.out.print(LocalDevice.isPowerOn());
localDevice = LocalDevice.getLocalDevice();
agent = localDevice.getDiscoveryAgent();
}

public void inquiry() throws BluetoothStateException {
agent.startInquiry(DiscoveryAgent.GIAC, this);
}

public void deviceDiscovered(RemoteDevice device, DeviceClass devClass) {
try {
Log.add("Device discovered: " + device.getFriendlyName(false));
} catch (IOException ex) {
Logger.getLogger("global").log(Level.SEVERE, null, ex);
}
}

public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
Log.add("Service discovered");
}

public void serviceSearchCompleted(int transID, int responseCode) {
Log.add("Service search completed");
}

public void inquiryCompleted(int discType) {
Log.add("Inquiry completed");
}

}


5. Log.java

/*
* Log.java
*
* Copyright (C) 2007 didiksoft
* http://java-vb.blogspot.com
*
*/

package com.didiksoft.logging;

import com.didiksoft.presence.Controller;

/**
*
* @author Didik Rawandi (uchiha_didik@yahoo.com)
*/
public class Log {

/** Creates a new instance of Log */
private Log() {
}

public static void add(String message) {
System.out.println("LOG: " + message);
Controller controller = Controller.getInstance();
controller.addLogText(message);
}

public static void error(String message) {
System.err.println("ERROR: " + message);
}

}



good luck, please clicks MyAds for donate myriset, thanks alot

No comments: