有人可以提供有关如何使用蓝牙cn1库读取和写入文本数据的示例代码吗?我尝试查看项目源代码(https://github.com/chen-fishbein/bluetoothle-codenameone)作为示例代码,但找不到任何使用适当的方法读/写文本数据。这些方法也没有任何Java文档。
答案 0 :(得分:1)
这是我用来发送的代码:
reloadData()
这里接收:
public void sendMessage(String message) {
if (Display.getInstance().isSimulator()) {
System.out.println(message);
} else {
// System.out.println("Sending message: " + message);
String b64WriteString = Base64.encode(message.getBytes());
try {
bt.write(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
}
}, deviceAddress, services.get(0), sendDataCharacteristic, b64WriteString, false);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
我为服务和特征UUID定义了字段。此外,可能不再需要callSerially。我想我记得CN1LIB已经更新了,但我确实不记得了。
对于该设备,服务特性为“6E400001-B5A3-F393-E0A9-E50E24DCCA9E”
sendCharacteristic是“0x0002”
receiveCharacteristic是“0x0003”
答案 1 :(得分:0)
在接受了James H的建议,以及更多的试验错误后,我终于设法让Adafruit的Bluefruit LE Friend之间的数据传输一致,至少在Android设备上。虽然不确定iOS,因为我还没有测试过它。以下是所需的关键代码。
首先,您需要服务,TX和RX特性UUID。找到了这些UUID here。注意,这些不一定是大写的。
public static final String UUID_SERVICE = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
public static final String UUID_RX = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
public static final String UUID_TX = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
接下来,扫描并找到设备后,调用connect()方法进行实际连接,然后严格调用discover()方法。一旦调用了discover()回调,就添加“subscriber”来接收数据。
private void connect(String address) {
bleAddress = address; // set the global BLE address
if (!connected) {
// start an infinite progress dialog
final Dialog ip = new InfiniteProgress().showInifiniteBlocking();
try {
bt.connect(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
ip.dispose();
Object obj = evt.getSource();
print("Connected to Bluetooth LE device ...\n" + obj, true);
// must be called on Android devices in order to load on the UUIDs, otherwise there is an error that service can't be found. Won't do anything on ios though?
discover();
connected = true;
}
}, address);
} catch (IOException ex) {
ip.dispose();
String message = "Error connecting to bluetooth device: " + address;
print(message + "\n" + ex.getMessage(), false);
}
} else {
String message = "BLE device already connected to: " + address;
print(message, false);
}
}
private void discover() {
try {
bt.discover(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
print("BLE Information Received ...", true);
addSubscriber();
}
}, bleAddress);
} catch (Exception ex) {
print(ex.getMessage(), false);
}
// if we running on is add the subscriber here since the above bt call
// does nothing?
if (Display.getInstance().getPlatformName().equals("ios")) {
print("Adding subscriber for iOS Device", true);
addSubscriber();
}
}
private void addSubscriber() {
try {
bt.subscribe(new ActionListener() {
StringBuilder sb = new StringBuilder();
@Override
public void actionPerformed(ActionEvent evt) {
JSONObject dataIncoming = (JSONObject) evt.getSource();
String base64Value = "";
try {
if (dataIncoming.getString("status").equals("subscribedResult")) {
base64Value = dataIncoming.getString("value");
}
} catch (JSONException e) {
console.setText("Error reading data: " + e.getMessage());
}
String message = new String(Base64.decode(base64Value.getBytes()));
sb.append(message);
if (message.endsWith("\r\n")) {
processData(sb.toString());
sb = new StringBuilder();
}
}
}, bleAddress, UUID_SERVICE, UUID_RX);
String message = console.getText() + "\nSubcriber added ...";
console.setText(message);
} catch (IOException ex) {
String message = "Error Subscribing: " + ex.getMessage();
console.setText(message);
}
}
因此,这将建立连接,发现服务,最后添加接收数据的订阅者方法,并严格使用缓冲区来收集接收的数据,直到收到CRLF字符。
然而,我遇到的另一个主要问题是BLE规范的默认23字节发送限制(可能只是Android问题?)。如果您尝试发送超过此数量,则连接将被删除,并且不会返回任何有意义的错误消息。为了解决这个问题,我使用了建议here的技术,它需要将数据拆分成20字节数组的块。由于我们发送常规ASCII文本,那么20个字符应该是20个字节,所以我只是将文本拆分成长度为20个字符的字符串。它不是最有效的,它更容易调试。
private void sendText(final String data) {
try {
String b64String = Base64.encode(data.getBytes());
bt.write(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if(data.endsWith("\r\n")) {
print("Data sent ...", true);
}
}
}, bleAddress, UUID_SERVICE, UUID_TX, b64String, false);
} catch (IOException ex) {
String message = "Error sending: " + data + "\n"
+ UUID_SERVICE + "\n"
+ UUID_TX + "\n"
+ ex.getMessage();
print(message, false);
}
}
private void splitAndSend(String text) {
text += "\r\n";
// first split data in chunk size of 20 chracters
ArrayList<String> sl = new ArrayList<>();
char[] data = text.toCharArray();
int len = data.length;
int chunkSize = 20;
for (int i=0; i < len; i+= chunkSize) {
sl.add(new String(data, i, Math.min(chunkSize,len - i)));
}
// now send chunks amd wait 100 ms to prevent any erros
for(String word: sl) {
sendText(word);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {}
}
}
可以找到包含GUI内容的完整源代码here,但这绝对是一项正在进行中的工作。