天天看點

J2ME的藍牙SPP連接配接實作

概述: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實作,代碼中已做詳細注釋。

繼續閱讀