我正在处理一个应该与Bluehood相同的应用程序,这是一个在谷歌市场上的应用程序。
所以现在我正在研究蓝牙。事实是,我想在两个设备之间传输字符串(JSON)。我在stackoverflow上看过很多帖子,在互联网上看到了一些例子,但对我来说并不是那么清楚。
我知道我已经使用createInsecureRfcommSocketToServiceRecord发送信息而listenUsingInsecureRfcommWithServiceRecord用于接收它们,但我正在搜索一些简单的教程来解释它是如何工作的以及如何在两个设备之间传输数据。
提前感谢您的解释......
答案 0 :(得分:2)
我很难知道我是否有效地回答了这个问题,因为你说你已经在网上搜索过,我在android com on Bluetooth找到了最有用的教程之一。我已经提供了代码的一部分,而不是完整的线程类,但是提供了一些关于如何使用临时套接字的信息,直到找到套接字并使其成为最终版本,在连接期间,以及线程如何管理每个阶段连接过程。
listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
用于创建服务器套接字。它侦听连接。它像一样服务于服务器。这是在充当服务器或侦听传入连接的设备上。
这是一个单独的线程。
public AcceptThread() {
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) {
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (BluetoothConnection.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice());
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new socket.
try {
socket.close();
} catch (IOException e) {
}
break;
}
}
}
}
}
有一个单独的线程充当客户端,寻求连接。它寻找连接。这是在寻求与服务器设备连接的设备上。 (这些可以互换)。
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
}
mmSocket = tmp;
}
public void run() {
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
}
connectionFailed();
return;
}
然后,您需要一个线程来管理实际连接。当客户端遇到服务器时。也在一个单独的线程中。
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
connectionLost();
// Start the service over to restart listening mode
BluetoothConnection.this.start();
break;
}
}
}
在此主题中,您还可以使用代码来管理通过此连接写入数据。
通过android.com提供samples。 我还发现this tutorial很好,作为蓝牙发现和连接的简单背景,虽然它没有为您提供读取和写入数据所需的全部内容。
在读取和写入数据方面,下面的代码片段是一种处理读取数据并将其解析为可用内容的方法示例。从连接线程中调用处理程序。在这种情况下,我将数据附加到textView,但您可以随意使用它,它显示了如何将它放入String中。 (这就是你要找的东西)。
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
textView1.append("\nMessage " + messageCount + ": " + readMessage);
....
同样,有一些代码可以编写消息 - 这是在连接的线程类中。但是,我使用OnClick事件和要发送的按钮来获取此信息。从EditText中获取文本并将其发送到函数以将String解析为字节。
其中message是一个String,mChatService正在从Connected线程调用write方法。 将字符串转换为字节数组,以便可以发送。
// Get the message bytes and tell the BTManager to write
byte[] send = message.getBytes();
mChatService.write(send);
从连接线程写入方法:
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
}
}
值得注意的是,必须监视设备的状态(您可以查看教程)。
保持背景线程远离UI也很重要。因此,这是技能进入(和处理程序)以将数据传输到UI或从UI传输到套接字连接的地方。