基於 JSR 82 (Java APIs for Bluetooth),本文演示完整 MIDlet:啟動設備發現 → 查詢 OBEX Push 服務 → 建立 ClientSession → 傳送文字文件。代碼已在 Nokia N95 與 Windows Vista 電腦間實測通過。
LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(GIAC, listener)agent.searchServices(null, new UUID[]{new UUID(0x1105L)}, device, listener)(0x1105 = OBEX Object Push)ServiceRecord.getConnectionURL() 取得 URL → Connector.open(url) 獲取 ClientSession → put(headers) → OutputStream.write()
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
try {
String name = btDevice.getFriendlyName(false);
deviceList.append(name, null); // List UI
devices.put(new Long(deviceList.size()), btDevice); // 索引→RemoteDevice
} catch (Exception e) { handleError(e); }
}
public void inquiryCompleted(int discType) {
if (deviceList.size() == 0) showAlert("未發現設備");
else display.setCurrent(deviceList);
}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
for (ServiceRecord sr : servRecord) {
String url = sr.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
serviceUrls.add(url); // 保存供用戶選擇
}
}
public void serviceSearchCompleted(int transID, int respCode) {
if (serviceUrls.isEmpty()) showAlert("無 OBEX Push 服務");
else showServiceSelectionUI();
}
private void sendNote(String url, String text) {
try {
ClientSession cs = (ClientSession) Connector.open(url);
cs.connect(null); // 空標頭連接
HeaderSet hs = cs.createHeaderSet();
hs.setHeader(HeaderSet.LENGTH, new Long(text.length()));
hs.setHeader(HeaderSet.NAME, "myNote.txt");
hs.setHeader(HeaderSet.TYPE, "text/plain");
Operation op = cs.put(hs);
OutputStream out = op.openOutputStream();
out.write(text.getBytes());
out.close();
op.close();
cs.disconnect(null);
cs.close();
showAlert("發送成功");
} catch (Exception e) {
handleError(e);
}
}
MIDlet-Permissions: javax.microedition.io.Connector.bluetooth.client,簽名應用體驗更佳。IOException、BluetoothConnectionException 皆需捕獲,網路不穩定時重試邏輯必要。
public class BTFileSender extends MIDlet implements DiscoveryListener, CommandListener {
private DiscoveryAgent agent;
private List deviceList, serviceList;
private Hashtable devices = new Hashtable(); // index -> RemoteDevice
private Vector serviceUrls = new Vector();
// ... UI 初始化、命令處理、上述回調實現、sendNote()...
}
ServerRequestHandler 接收文件,配合 SessionNotifier 監聽連入。ServiceRecord.getAttributeIDs() 獲取服務名、描述、圖標等。ServiceRecord.AUTHENTICATE_ENCRYPT 強制加密通道。