概述:J2ME的藍牙實作需要JSR82的支援,下面是一個建立SPP連接配接用戶端的具體例子,分析請參看代碼注釋。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;
import javax.bluetooth.*;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class BtSppMid extends MIDlet implements Runnable, CommandListener, ItemCommandListener {
public StreamConnection client = null;
//Bluetooth SPP 資料流
public DataInputStream dis = null;
public DataOutputStream dos = null;
public boolean running; //線程運作标志
public Display display = null;
public Form form = new Form("JB00 Bluetooth suite");
private Command cmdExit = new Command("Exit", Command.EXIT, 1);
private Command cmdConnect1 = new Command("Connect1", Command.SCREEN, 1); //連接配接查找到的SPP服務
private Command cmdSearch = new Command("Search device", Command.SCREEN, 1); //查找藍牙裝置
private Command cmdSrchService = new Command("Search service", Command.SCREEN, 1); //查找藍牙服務
private Command cmdStopSrch = new Command("Stop", Command.SCREEN, 1); //停止藍牙裝置搜尋
private Command cmdOK = new Command("OK", Command.OK, 1); //查找到裝置後直接連接配接其SPP服務
public Command cmdConnect = new Command("Connect", Command.ITEM, 1);
DiscoveryAgent discoveryAgent;
DiscoveryListener discoveryListener;
//用于儲存搜尋到的裝置
Vector devices = new Vector();
Vector devName = new Vector();
Vector devAdr = new Vector();
Vector devItem = new Vector();
//用于儲存搜尋到的服務
Vector services = new Vector();
//伺服器服務記錄
ServiceRecord record=null;
//搜尋所得的裝置位址
String deviceAddr;
String conURL;
public BtSppMid() {
super();
form.addCommand(cmdExit);
form.addCommand(cmdSearch);
form.setCommandListener(this);
discoveryListener = new MyDiscoveryListener(this);
}
protected void startApp() throws MIDletStateChangeException {
display = Display.getDisplay(this);
display.setCurrent(form);
running = true;
try {
LocalDevice localDevice = LocalDevice.getLocalDevice();
discoveryAgent = localDevice.getDiscoveryAgent();
form.append("Bluetooth ready, please search device first./n");
} catch (BluetoothStateException e) {
form.append("Failed to use bluetooth!/nYou'd better checkout your bluetooth status./n");
pauseApp();
}
}
protected void pauseApp() {
// close();
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
running = false;
close();
}
public void commandAction(Command cmd, Displayable d) {
if (cmd == cmdExit) {
notifyDestroyed();
}
else if (cmd == cmdSearch)
{
try
{
//開始進行藍牙裝置查找
discoveryAgent.startInquiry(DiscoveryAgent.GIAC,discoveryListener);
form.append("Searching BT device../n");
}
catch (Exception e)
{
form.append("Searching error!/n");
return;
}
form.removeCommand(cmdSearch);
form.addCommand(cmdStopSrch);
form.addCommand(cmdSrchService); //添加發現服務指令
}
else if (cmd == cmdSrchService)
{
UUID uuid[] = {new UUID(0x1101)}; //0x1101是藍牙SPP服務所對應的UUID
for (int i=0;i<devices.size();i++)
{
RemoteDevice btDevice = (RemoteDevice)devices.elementAt(i);
try
{
discoveryAgent.searchServices(null, uuid, btDevice, discoveryListener); //在發現的裝置上查找SPP服務
form.append("searching service../n");
} catch (IOException e) {
form.append("Search error!/n");
return;
}
break;
}
form.removeCommand(cmdSrchService);
form.addCommand(cmdConnect1);
}
else if (cmd == cmdConnect1)
{
conURL = ((ServiceRecord)services.elementAt(0)).getConnectionURL(0,false); //連接配接第一個被查找到的裝置
form.append("Trying to connect1 "+conURL+"/n");
//開始藍牙連接配接線程
new Thread(this).start();
}
else if (cmd == cmdStopSrch)
{
discoveryAgent.cancelInquiry(discoveryListener); //停止藍牙裝置查找/
}
}
public void run() {
client = null;
try {
client = (StreamConnection)Connector.open(conURL); //連接配接指定裝置的SPP服務
form.append("Connected./n");
dis = client.openDataInputStream();
dos = client.openDataOutputStream();
form.removeCommand(cmdConnect);
form.removeCommand(cmdConnect1);
form.removeCommand(cmdSrchService);
form.removeCommand(cmdStopSrch);
for(int i=0; i<devItem.size(); i++)
{
//連接配接成功後,移除所有裝置所對應StringItem的連接配接指令
StringItem si = (StringItem)devItem.elementAt(i);
si.removeCommand(cmdConnect);
}
} catch (Exception e) {
form.append("Connect error!/n");
close();
return;
}
}
public void commandAction(Command c, Item item) {
String deviceName;
if(c == cmdConnect) //連接配接該裝置的SPP服務
{
deviceName = ((StringItem)item).getText();
for (int i=0;i<devName.size();i++)
{
if((String)devName.elementAt(i) == deviceName)
{
deviceAddr = (String) devAdr.elementAt(i); //從儲存的裝置位址中擷取藍牙位址
conURL = "btspp://"+deviceAddr+":1";
form.append("Connecting "+deviceName+"../n");
//開始藍牙連接配接線程
new Thread(this).start();
break;
}
}
}
}
public void close() {
try {
if (dis != null) {
dis.close();
dis = null;
}
if (dos != null) {
dos.close();
dos = null;
}
if (client != null) {
client.close();
client = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendDataToBluetooth(String data)
{
try
{
dos.write(data.getBytes());
dos.flush();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
//藍牙裝置發現、服務發現處理
class MyDiscoveryListener implements DiscoveryListener {
BtSppMid midlet;
public MyDiscoveryListener(BtSppMid midlet) {
this.midlet = midlet;
}
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
String name = null;
StringItem tmpItem;
try {
name = btDevice.getFriendlyName(false); //查找裝置名稱
} catch (IOException e) {
}
//發現裝置後,将其作為StringItem在螢幕上顯示,以添加指令,并存入vector
tmpItem = new StringItem(null, name);
midlet.devItem.addElement(tmpItem);
midlet.form.append((StringItem)midlet.devItem.lastElement());
midlet.devices.addElement(btDevice);
}
public void inquiryCompleted(int discType) {
for(int i=0; i<midlet.devices.size(); i++)
{
StringItem si = (StringItem)midlet.devItem.elementAt(i);
RemoteDevice rd = (RemoteDevice)midlet.devices.elementAt(i);
String name = null;
String adr = null;
try {
name = rd.getFriendlyName(false);
adr = rd.getBluetoothAddress();
midlet.devName.addElement(name);
midlet.devAdr.addElement(adr);
} catch (IOException e) {
}
si.setText(name); //設定StringItem為裝置名稱
}
midlet.form.append("/nSearching complete./n");
for(int i=0; i<midlet.devItem.size(); i++)
{
StringItem si = (StringItem)midlet.devItem.elementAt(i);
si.setDefaultCommand(midlet.cmdConnect); //為每個裝置添加連接配接指令
si.setItemCommandListener(midlet);
}
}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
if(servRecord.length > -1)
{
for(int i = 0; i < servRecord.length; i++)
{
midlet.services.addElement(servRecord[i]);
midlet.form.append(servRecord[i].toString()+"/n");
}
}
else{
midlet.form.append("No service found!/n");
}
}
public void serviceSearchCompleted(int transID, int responseCode) {
midlet.form.append(responseCode+" is the srching result./n");
}
}
上面的代碼實作了查找藍牙裝置、查找指定裝置的藍牙服務、連接配接指定裝置的藍牙虛拟序列槽SPP服務,并有相應的UI實作,代碼中已做詳細注釋。