VI.Bluetooth Communication

Ứng dụng Bluetooth đã thực hiện các phần sau đây để giao tiếp: khởi tạo stack, thiết lập chế độ discovery, discovery thiết bị, decovery dịch vụ và kết nối.

1.Khởi tạo stack

Trong các thiết bị Bluetooth, stack Bluetooth được sử dụng để điều khiển thiết bị. Vì vậy, nó nên được khởi tạo đầu tiên trước khi bắt đầu. Sau khi được khởi tạo, các thiết bị sẽ sẵn sàng để sử dụng.

Đặc tả JSR 82 cung cấp lớp LocalDevices. Lớp này được gọi như là một entry point cơ sở, và nó giúp khởi tạo stack. Điều này cũng được sử dụng để kiểm soát các cài đặt Bluetooth cục bộ. Lớp LocalDevice cung cấp mức thấp nhất để truy cập vào stack Bluetooth, ngoài ra nó còn câp cấp khả năng truy cập thông tin về thiết bị Bluetooth của riêng bạn.

Để khởi tạo stack, ta đơn giãn chỉ cần gọi phương thức tĩnh LocalDevice.getLocalDevice().

2.Chế độ Discovery

Để thiết lập chế độ Discovery, ta chỉ cần gọi phương thức LocalDevice.setDiscoverable(int mode). JSR 82 hỗ trợ các kiểu sau:

  • DiscoveryAgent.GIAC
  • DiscoveryAgent.LIAC
  • DiscoveryAgent.NOT_DISCOVERABLE

Một thiết bị Bluetooth có thể chứa nhiều thiết lập chế độ Discovery. Ví dụ, một thiết bị có thể cấu hình để không bị discovery, lúc này các thiết bị Bluetooth khác trong phạm vi cho phép không thể phát hiện ra thiết bị Bluetooth này. Mặc khác, một thiết bị Bluetooth có thể cấu hình để được discovery bởi các thiết bị khác, và trong trường hợp này, chế độ Discovery chính là GIAC(General Unlimited Inquiry Access Code).

Một thiết bị Bluetooth cũng có thể cấu hình để có thể được discovery “limited” bởi những thiết bị Bluetooth khác bằng cách sử dụng một limited inquiry. Bằng cách này,        chế độ discovery được thiết lập sử dụng Limited Dedicated Inquiry Access Code(LDIAS).

Thông thường, một inquiry được thực hiện với GIAC. Để hủy bỏ thiết lập chế độ discovery này, ta thiết lập chế độ NOT_DISCOVERABLE.

Nó sẽ trả về true hoặc false sau khi thiết lập chế độ discovery. Nếu trả về false có nghĩa là thiết bị không hỗ trợ kiểu truy vấn này.

/* Retrieve the local device to get to the Bluetooth Manager*/

localDevice = LocalDevice.getLocalDevice();

/* Set the discoverable mode to GIAC*/

localDevice.setDiscoverable(DiscoveryAgent.GIAC);

3.Discovery thiết bị

Lớp DiscoveryAgent và giao diện DiscoveryListener sẽ cung cấp các dịch vụ discovery cần thiết. Sau khi nhận đối tượng LocalDevice, khởi tạo một đối tượng DiscoveryAgent bằng cách gọi phương thức LocalDevice.getDiscoveryAgent().

/* Retrieve the local device to get to the Bluetooth Manager*/
localDevice = LocalDevice.getLocalDevice();
/* set the discoverable mode to GIAC*/
localDevice.setDiscoverable(DiscoveryAgent.GIAC);
/*retrieve the discovery agent*/
discoveryAgent = localDevice.getDiscoveryAgent();

Có 2 cách để nhận được một danh sách các thiết bị truy cập(RemoteDevice) sử dụng DiscoveryAgent:

  • Discovery.startInquiry(int accessMode, DiscoveryListener listener): phương thức này đặt thiết bị vào chế độ inquiry, ứng dụng phải chỉ định một DiscoveryListener để đáp ứng các sự kiện liên quan đến inquiry để tận dụng chế độ này. Phương thức DiscoveryListener.deviceDiscovered() được gọi mỗi khi một inquiry được tìm thấy. Phương thức DiscoveryListener.inquiryCompleted() được gọi khi inquiry được hoàn tất hay bị hủy bỏ.
  • DiscoveryAgent.retrieveDevices(int retrieveOption): phương thức này sử dụng để nhận một danh sách các thiết bị hiện tại nếu thiết bị không đợi các thiết bị khác discovery. Tùy thuộc vào tham số retrieveOption, phương thức này sẽ trả về danh sách các thiết bị được  tìm thấy trong inquiry trước đó(CACHED) hoặc một danh sách trước đó được biết đến.
public class BTDiscovery implements DiscoveryListener{
...
/* retrieve the discovery agent */
DiscoveryAgent agent = local.getDiscoveryAgent();

/* place the device in inquiry mode*/
boolean complete = 
agent.startInquiry(DiscoveryAgent.GIAC, this);
...
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
            form.append(”Device discovered: “+btDevice.getBluetoothAddress());
}

public void inquiryCompleted(int discType) 
 switch (discType) {
  case DiscoveryListener.INQUIRY_COMPLETED :
   form.append(”INQUIRY_COMPLETED”);
  break;
  case DiscoveryListener.INQUIRY_TERMINATED :
   form.append(”INQUIRY_TERMINATED”);
  break;
  case DiscoveryListener.INQUIRY_ERROR :
   form.append (”INQUIRY_ERROR”);
  break;
  default :
   form.append (”Unknown Response Code”);
  break;
}
}
}
/ * Lấy PREKNOWN thiết bị * /
RemoteDevice[] devices = agent.retrieveDevices( RemoteDevice [] thiết bị = agent.retrieveDevices (
DiscoveryAgent.PREKNOWN); DiscoveryAgent.PREKNOWN);

/*Retrieve CACHED devices */ / * Lấy các thiết bị lưu trữ * /
RemoteDevice[] devices = agent.retrieveDevices( RemoteDevice [] thiết bị = agent.retrieveDevices (
DiscoveryAgent.CACHED); DiscoveryAgent.CACHED);

Lớp RemoteDevice đại diện cho một thiết bị kết nối từ xa và cung cấp các phương thức để nhân thông tin, chẳng hạn như: địa chỉ, tên về thiết bị.

4.Discovery dịch vụ

Một khi các thiết bị cục bộ đã phát hiện ít nhất một thiết bị từ xa, nó có thể bắt đầu tìm kiếm các dịch vụ có sẵn. Bởi vì discovery dịch vụ cũng tương tự như discovery thiết bị, nên DiscoveryAgent cũng cung cấp các phương thức  để discovery các dịch vụ trên thiết bị server Bluetooth và khởi tạo các giao dịch discovery dịch vụ. Lưu ý rằng, API cung cấp các kỹ thuật để tìm kiếm các dịch vụ từ xa nhưng không phải các dịch vụ trên thiết bị cục bộ.

Phương thức servicesDiscovered() và serviceSearchCompleted() của lớp DiscoveryAgent phải được cài đặt. Chúng sẽ xử lý các sự kiện xảy ra khi các dịch vụ được tìm thấy hay khi discovery dịch vụ được hoàn tất.

public class BTDiscovery implements DiscoveryListener{
...
/* retrieve the discovery agent */
DiscoveryAgent agent = local.getDiscoveryAgent();

/* place the device in inquiry mode*/
boolean complete = 
agent.startInquiry(DiscoveryAgent.GIAC, this);
...

public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass cod) {

int[] attributes = {0x100,0x102,0x102};
/*
* Supplying UUIDs in an UUID array enables searching for
* specific services. 
*/
UUID[] uuids = new UUID[1];
uuids[0] = new UUID(0x1002);
try {
agent.searchServices(attributes,uuids, remoteDevice,this);
} catch (BluetoothStateException e) {
/* Error handling code here*/
}
}

public void inquiryCompleted(int discType) 
{
}
public void servicesDiscovered(int transID,
ServiceRecord [] serviceRecord) {
/* Services discovered, keep reference to the ServiceRecord
* array
*/
servicesFound = serviceRecord;
}
public void serviceSearchCompleted(int transID, int respCode) {
switch(respCode) {
case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
/*
* Service search completed successfully
* Add appropriate code here
*/
break;
case
DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
/* device not reachable, add appropriate code here*/
break;
case DiscoveryListener.SERVICE_SEARCH_ERROR:
/* Service search error, add appropriate code here*/
break;
case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
/* No records found, add appropriate code here*/
break;
case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
/*
* Search terminated by agent.cancelServiceSearch()
* Add appropriate code here
*/
break;
}

Đầu tiên, các dịch vụ nên được đăng ký hay quảng bá trên một thiết bị Bluetooth server trước khi nó được discovery. Server sẽ thực hiện một số công việc như: tạo ra một bản ghi dịch vụ để mô tả dịch vụ được cung cấp, chấp nhận các kết nối từ client và thêm bản ghi vào cơ sở dữ liêu discovery dịch vụ(Service Discovery Database).

5.Kết nối

Như đã đề cập trong phần trên, các kết nối Bluetooth được dựa trên giao thức L2CAP, một gói dữ liệu giao thức cấp thấp, và RFCOMM. Các kết nối Bluetooth được tạo ra bằng cách gọi phương thức Connector.open() dựa trên Generic Connection FrameWork(GCF). Kiểu kết nối URL được tạo ra có cú pháp sau:

Định dạng URL cho kết nối L2CAPConnection:

btl2cap://hostname:[PSM | UUID];parameters

Định dạng URL cho kết nối RFCOMM StreamConnection:

btspp://hostname:[CN | UUID];parameters

Trong đó:

  • hostname: hoặc địa chỉ thiết lập một kết nối server hoặc địa chỉ Bluetooth để tạo ra một kết nối client.
  • PSM: là một giá trị Protocol/Service Multiplexer, sử dụng cho một kết nối client tới server.
  • UUID là một Universally Unique Identifier sử dụng khi thiết lập một dịch vụ trên server. Mỗi một UUID phải được đảm bảo rằng nó là duy nhất trong toàn bộ thời gian và không gian.
  • parameters:  mô tả tên các dịch vụ và các thông số bảo mật xác thực, ủy quyền và mã hóa.

Ví dụ: chuỗi URL cho Server RFCOMM:

btspp://localhost:2D26618601FB47C28D9F10B8EC891363;authenticate=false; encrypt=false;name= rfcommtest

Hay chuỗi URL cho Client RFCOMM:

btspp://0123456789AF:1;master=false;encrypt=false;authenticate=false

Sử dụng localhost làm hostname cho biết rằng bạn muốn có một kết nối server. Để tạo kết nối client đến một thiết bị được biết đến và dịch vụ, sử dụng URL kết nối của dịch vụ, được tìm thấy trong ServiceRecord.

Ví dụ dưới đây mô tả kết nối server RFCOMM:

...
/* Bluetooth Service name*/
private static final String myServiceName = " rfcommtest ";

/* Bluetooth Service UUID of interest*/
private static final String myServiceUUID = "2d26618601fb47c28d9f10b8ec891363";
private UUID MYSERVICEUUID_UUID = new UUID(myServiceUUID, false);
...
/* Define the server connection URL*/
String connURL = "btspp://localhost:"+MYSERVICEUUID_UUID.toString()+";"+name="+myServiceName;
...
/* Create a server connection (a notifier)*/
StreamConnectionNotifier scn = (StreamConnectionNotifier) Connector.open(connURL);
...
/*Accept a new client connection*/
StreamConnection sc = scn.acceptAndOpen();
...

Đoạn code dưới đây mô tả một kết nối client với một dịch vụ cho trước sử dụng service record của nó.

... 
/* Given a service of interest, get its service record*/
ServiceRecord sr = (ServiceRecord)discoveredServices.elementAt(i);
/* Then get the service's connection URL*/
String connURL = sr.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
/* Open connection*/
StreamConnection sc = (StreamConnection) Connector.open(connURL);
 ...

6.Đăng ký dịch vụ

Trước khi dịch vụ được discovery, nó phải được đăng ký – được quảng bá trên thiết bị Bluetooth server. Server có trách nhiệm:

6.1. Tạo ra một bản ghi dịch vụ để mô tả các dịch vụ cung cấp

Việc thực thi Bluetooth sẽ tự động tạo ra một bản ghi dịch vụ khi ứng dụng tạo ra một thông báo dạng kết nối hoặc một StreamConnectionNotifier hoặc một L2CAFConnectionNotifier.

Đoạn code sau đây định nghĩa và khởi tạo một thông báo dạng kết nối RFCOMM, dẫn tới tạo ra một bản ghi dịch vụ:

...
StreamConnectionNotifier streamConnectionNotifier;
/* Create notifier (and service record)*/
streamConnectionNotifier = (StreamConnectionNotifier)Connector.open(connectionURL);
...

6.2.Đăng ký dịch vụ và thêm vào database một bản ghi dịch vụ

Một khi bạn tạo ra một thông báo kết nối và bản ghi dịch vụ, server đã sẵn sàng để đăng ký dịch vụ và đợi client. Việc gọi phương thức acceptAndOpen(), phần thực thi Bluetooth sẽ chèn một bản ghi dịch vụ cho kết nối được kết hợp vào database, điều này làm dịch vụ visible đối với client.

...
/* Insert service record into SDDB and wait for an incoming client*/
StreamConnection conn = streamConnectionNotifier.acceptAndOpen();
...

6.3.Cập nhật bản ghi dịch vụ trong database bất cứ lúc nào thay đổi thuộc tính của dịch vụ

Bạn có thể lấy bản ghi dịch vụ từ databse bằng cách gọi phương thức LocalDevice.getRecord(), để thêm hay thay đổi thuộc tính thì gọi phương thức ServiceRecord.setAttributeValue(), và ghi(write) bản ghi dịch vụ vào database bằng cách gọi phương thức LocalDevice.updateRecord().

...
try {
    /* Retrieve service record and set/update optional attributes, 
     for example, ServiceAvailability, indicating service is available*/
    sr = localDevice.getRecord(streamConnectionNotifier);
    sr.setAttributeValue(SDP_SERVICEAVAILABILITY,
        new DataElement(DataElement.U_INT_1, 0xFF));
    localDevice.updateRecord(sr);
} catch (IOException ioe) {
    /* Catch exception, display error*/
}
...

6.4.Xóa hay disable bản ghi dịch vụ trong database khi dịch vụ không còn available

Khi dịch vụ không còn cần thiết, xóa nó ra khỏi database bằng cách đóng thông báo kết nối.

...
streamConnectionNotifier.close();
...

a.Các bước dưới đây mô phỏng server sử dụng RFCOMM

B1: Xét lớp LocalDevice, đại diện cho các chức năng cơ bản của quản lý Bluetooth. Nó cung cấp mức thấp nhất có thể của giao diện vào Bluetooth stack. Nó là đối tượng dạng Singleton

localDevice = LocalDevice.getLocalDevice();

B2: Thiết lập chế độ discovery theo đoạn code sau:

localDevice.setDiscoverable(DiscoveryAgent.GIAC);

Tham số DiscoveryAgent.GIAC sử dụng để chỉ định kiểu của inquiry để hoàn tất hay đáp ứng.

B3: Gọi phương thức Connector.open(String URL) để tạo ra một bản ghi dịch vụ để đại diện cho dịch vụ và cast kết quả vào StreamConnectionNotifier:

StreamConnectionNotifier notifier= (StreamConnectionNotifier)Connector.open(SERVERURL);

Tiếp theo, ta gọi phương thức acceptAndOpen(), phương thức này sẽ tạm dừng thread và đợi giao dịch xảy ra.

b.Các bước để tạo ra Client sử dụng RFCOMM

B1:Client có một tiến trình khác để khởi tạo stack Bluetooth.

LocalDevice localDevice = LocalDevice.getLocalDevice();
discoveryAgent = localDevice.getDiscoveryAgent(); 
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);

B2.Client phải thực thi giao diện DiscoveryListener.

Điều này cho phép một ứng dụng các sự kiện discover thiết bị và dịch vụ. Giao diện này có 4 phương thức, 2 cho discover thiết bị và 2 cho discovery dịch vụ.

  • deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
    Được gọi khi một thiết bị được tìm thấy trong suốt quá trình inquiry.
  • inquiryCompleted(int discType)
    Được gọi khi một inquiry được hoàn tất.
  • servicesDiscovered(int transID, ServiceRecord[] servRecord)
    Được gọi khi dịch vụ được tìm thấy trong quá trình tìm kiếm.
  • serviceSearchCompleted(int transID, int respCode)
    Được gọi khi tìm kiếm dịch vụ được hoàn tất hay kết thúc bởi một lỗi nào đó.

B3.Để có những dịch vụ URL

public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {    
    // in this example there is only one service
    for(int i=0;i<servRecord.length;i++) {       
       serviceUrl = servRecord[i].getConnectionURL(0,false);
    }    
  }

B4.Để có đáp ứng server

public void serviceSearchCompleted (int transID, int responseCode) (
... ...
conn = (StreamConnection)Connector.open(serviceUrl); conn = (StreamConnection) Connector.open (serviceUrl);
... ...
OutputStream output = conn.openOutputStream(); OutputStream output = conn.openOutputStream ();
... ...
InputStream inputStream = conn.openInputStream(); InputStream inputStream = conn.openInputStream ();
... ...
}

Cuối cùng đóng tất cả các kết nối

Conn.close();
Output.close();
inputStream.close();

7.Giao tiếp

Hai thiết bị phải chia sẽ giao thức giao tiếp chung để sử dụng một dịch vụ trên một thiết bị từ xa đến thiết bị cụ bộ. Sự chia sẽ này cho phép ứng dụng truy cập vào các dịch vụ truy cập rộng lớn, Bluetooth API cung cấp kỹ thuật kết nối tới bất kỳ dịch vụ nào sử dụng giao thức RFCOMM, L2CAP hay OBEX làm giao thức của nó. Nếu dịch vụ sử dụng giao thức khác như TCP/IP nằm trên những giao thức trên, thì ứng dụng có thể sử dụng các dịch vụ nhưng chỉ khi nó thực hiện các giao thức bổ xung trong ứng dụng, sử dụng CLDC Generic Connection Framework. URL sử dụng như là một bản ghi dịch vụ với các số và ký tự, ví dụ:

btspp://AAAAAAAAA11111111111111:8

Điều này có nghĩa client nên sử dụng Bluetooth Serial Port Profile(btspp://) để thiết lập kết nối với máy chủ kênh 8 trên thiết bị với địa chỉ AAAAAAAAA11111111111111. Địa chỉ thiết bị cũng tương tự như địa chỉ vật lý của máy tính.

VII.Ví dụ

1.Lớp BluetoothDemo

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.Choice;
import javax.bluetooth.UUID;

public final class BluetoothDemo extends MIDlet implements CommandListener {

  /* Shared UUID by server and client */
  public static final UUID RFCOMM_UUID = new UUID(0x0003);
  /*Soft key names*/
  private static final String SELECT = "Select";
  private static final String EXIT   = "Exit";

  /* Soft-keys*/
  private final Command CMD_EXIT = new Command(EXIT, Command.EXIT, 1);
  private final Command CMD_SLECT = new Command(SELECT, Command.SCREEN, 2);

  /*  String array show on list */
  private static final String[] MENULABLES = {"Server", "Client" };
  /*List*/
  private final List menu = new List("Bluetooth Echo Demo", Choice.IMPLICIT, MENULABLES,    null);  
  /*Display*/
  private Display display     = null;

  public BluetoothDemo() {
    menu.addCommand(CMD_EXIT);
    menu.addCommand(CMD_SLECT);
    menu.setCommandListener(this);
  }

  public void startApp() {
    display = Display.getDisplay(this);
    display.setCurrent(menu);
  }

  protected void destroyApp(boolean unconditional) {
  }

  protected void pauseApp() {
  }

  public void commandAction(Command cmd, Displayable d) {
   if (cmd == CMD_EXIT) {
    destroyApp(true);
    notifyDestroyed();
    return;
   }
   else if (cmd == CMD_SLECT) {
    switch (menu.getSelectedIndex()) {
            case 0:
           /*Create the Server Object*/
           new Server(display);
            break;
            case 1:
           /*Create the Client Object*/
               new Client(display);
            break;
    }
   }
  }
}

2.Lớp Server

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.BluetoothStateException;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class Server implements Runnable{

 private StreamConnectionNotifier notifier;
 private StreamConnection conn;
 private LocalDevice localDevice;
 private boolean isInit;
 private static final String SERVERURL = "btspp://localhost:"+
  BluetoothDemo.RFCOMM_UUID +";name=rfcommtest;authorize=false";
 private Display display = null;
 private final Form form = new Form("Server...");//,
 //"Searching for Client...", 50, TextField.ANY);
 private static final String SERVERMSG = "\nHello Form Server...";

 public Server(Display dis) {
  display = dis;
  display.setCurrent(form);
  isInit = false;
  Thread thread = new Thread(this);
  thread.start();
 }

 public void run() {
  if (!isInit) {
    /* Initialization is done in the thread to avoid dead lock 'isInit'*/
    /*ensures it is done once only*/
   try {
     conn = null;
     form.append("Searching for Client...");
     localDevice = LocalDevice.getLocalDevice();
     localDevice.setDiscoverable(DiscoveryAgent.GIAC);
     notifier = (StreamConnectionNotifier)Connector.open(SERVERURL);
    } catch (BluetoothStateException e) {
     form.append("BluetoothStateException: " +e.getMessage());
    } catch (IOException e) {
     form.append("IOException: " + e.getMessage());
    }
    isInit = true;
   }
   try {
    /* Pauses thread until Transmission occurs*/
    conn = notifier.acceptAndOpen();
    OutputStream output = conn.openOutputStream();
    output.write(SERVERMSG.length()); // length is 1 byte
    output.write(SERVERMSG.getBytes());
    output.close();
    InputStream inputStream = conn.openInputStream();
    int length = inputStream.read();
    byte[] data = null;
    data = new byte[length];
    length = 0;
    /* Assemble data*/
    while (length != data.length) {
     int ch = inputStream.read(data, length, data.length - length);
     if (ch == -1) {
       throw new IOException("Can't read data");
     }
     length += ch;
    }
    String msg = new String(data);
    form.append(msg);
    inputStream.close();
    conn.close();
    notifier.close();
   } catch (Exception ex) {
    form.append("Bluetooth Server Running Error: " + ex);
   }
 }
}

3.Lớp Client

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.UUID;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.ServiceRecord;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.Connector;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;

public class Client implements DiscoveryListener {
 private DiscoveryAgent discoveryAgent;
 private UUID[] uuidSet;
 private String serviceUrl;
 private Display display = null;
 private StreamConnection conn = null;
 private final Form form = new Form("Client...");
 private static final String CLIENTMSG = "\nHello From Client..";

 public Client(Display dis) {
  display = dis;
  display.setCurrent(form);
  try {      
   LocalDevice localDevice = LocalDevice.getLocalDevice();
   discoveryAgent = localDevice.getDiscoveryAgent();
   discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
   form.append("\nstart Inquiry...");
   form.append("\nSearching for device...");
  } catch (Exception e) {
   form.append(“exception ”+e);
  }
 }

 public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
  try {
   /* Get Device Info*/
   form.append("\nDevice Discovered");
   form.append("\nMajor Device Class: " + cod.getMajorDeviceClass() +
    "Minor Device Class: "+ cod.getMinorDeviceClass());
   form.append("\nBluetooth Address: " + btDevice.getBluetoothAddress());
   form.append("\nBluetooth Friendly Name: " + btDevice.getFriendlyName(true));
   /* Search for Services*/
   uuidSet = new UUID[1];
   uuidSet[0] = BluetoothDemo.RFCOMM_UUID;
   int searchID = discoveryAgent.searchServices(null,uuidSet,btDevice,this);
  } catch (Exception e) {
     form.append("\nDevice Discovered Error: " + e);
  }
 }

 public void inquiryCompleted(int discType) {
   form.append("\nInquiryCompleted");
 }

 public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
  /*handling only one service*/
  form.append("\nServicesDiscovered");
  for(int i=0;i<servRecord.length;i++) {
   serviceUrl = servRecord[i].getConnectionURL(0,false);
  }
 }

 public void serviceSearchCompleted(int transID, int responseCode) {
  if(responseCode == SERVICE_SEARCH_ERROR)
    form.append("\nSERVICE_SEARCH_ERROR\n");

    if(responseCode == SERVICE_SEARCH_COMPLETED) {
      form.append("\nSERVICE_SEARCH_COMPLETED\n");
      form.append("\nService URL: " + serviceUrl);
      try {
             Alert alert = new Alert("Info...","Server Responding...",null,AlertType.INFO);
             alert.setTimeout(1200);
         conn = (StreamConnection)Connector.open(serviceUrl);
             OutputStream output = conn.openOutputStream();
             InputStream inputStream = conn.openInputStream();
         int length = inputStream.read();
             byte[] data = null;
         data= new byte[length];
         length = 0;
         // Assemble data
         while (length != data.length)
             {
              int ch = inputStream.read(data, length, data.length - length);
              if (ch == -1) {
           throw new IOException("Can't read data");
          }
          length += ch;
             }
         String msg = new String(data);
             form.append(msg);
             display.setCurrent(form);
             output.write(CLIENTMSG.length());
             output.write(CLIENTMSG.getBytes());
             output.close();
      }catch (Exception ex) {
            form.append (“exception ”+ex);
      } finally {
            try {
              conn.close();
            } catch (IOException ioe) {
              form.append("Error Closing connection " + ioe);
        }
      }
    }
    if(responseCode == SERVICE_SEARCH_TERMINATED)
      form.append("\nSERVICE_SEARCH_TERMINATED\n");

    if(responseCode == SERVICE_SEARCH_NO_RECORDS)
      form.append("\nSERVICE_SEARCH_NO_RECORDS\n");

    if(responseCode == SERVICE_SEARCH_DEVICE_NOT_REACHABLE)
      form.append("\nSERVICE_SEARCH_DEVICE_NOT_REACHABLE\n");
  }  
}

Bạn thấy bài viết này thế nào?
Các bài liên quan:
Bluetooth API - JSR 82 - Phần 2