我有两个Android设备,我想使用蓝牙连接它们,并通过RFCOMM通道传输数据。我只有一个设备接收数据,而另一个设备发送它…
使用此代码,我可以连接到另一个设备并开始侦听RFCOMM通道:
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
socket = (BluetoothSocket) m.invoke(device, 2);
socket.connect();
class BasicThread implements Runnable{
public void run() {
try {
InputStream stream = socket.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(stream));
while (true){
Log.d("myapp", "now listening...");
latestLine = r.readLine();
Log.d("myapp", latestLine);
}
} catch (IOException e) {
}
}
}
new Thread(new BasicThread()).run();
使用另一个设备,我实现了一个像这样的监听套接字:
Method m = blue.getClass().getMethod("listenUsingRfcommOn", new Class[] { int.class });
BluetoothServerSocket socket = (BluetoothServerSocket) m.invoke(blue, 2);
BluetoothSocket sock = socket.accept();
Log.d("myapp", "Connected...nnnnnnnn");
OutputStream s = sock.getOutputStream();
final PrintWriter out = new PrintWriter(s);
它们都在RFCOMM信道2上连接,并且都互相查看,但是,第二个设备总是在BluetoothSocket sock = socket.accept();
上保持阻塞
有什么帮助吗?
好吧,我是新手,但我可以尽力帮忙。这是我的经验,我设法使用反射连接了两个设备。我的Android手机使用方法listenUsingInsecureRfcommOn
接收数据,而其他设备是通信的主机,并通过BT SPP发送数据。我对这种方法有问题,因为它没有可见的SDP记录,所以我无法用其他设备检测到它。正因为如此,我使用Bluecove和JavaSE制作了一个小型嗅探器,试图连接到给定范围内的每个端口。这是代码:
package application.test;
import static java.lang.System.out;
import java.io.InputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
public class RfCommClient {
public static void main(String args[]) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
String add = "btspp://8C71F894A36D:";
String par = ";authenticate=false;encrypt=false;master=true";
String url = null;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd;HH-mm-ss-SSS");
for (int i = 1; i < 15; ++i) {
try {
url = add + i + par;
out.format("Time: %s, port = %dn", sdf.format(System.currentTimeMillis()), i);
StreamConnection conn = (StreamConnection) Connector.open(url);
PrintStream ops = new PrintStream(conn.openOutputStream());
ops.println("Hi there...");
// response
Thread.sleep(1000);
InputStream is = conn.openInputStream();
byte[] resp = new byte[5];
int r = is.read(resp);
out.println("r = " + r + ", response = " + new String(resp, "US-ASCII"));
Thread.sleep(10 * 1000);
conn.close();
} catch (Exception e) {
out.println("Exception occured, time = " + sdf.format(System.currentTimeMillis()) + ", i = " + i);
//e.printStackTrace();
}
}
}
}
我所了解到的是,有些端口被占用,有些端口无法使用(如文档所示,例如端口0)。例如,我认为端口2被占用了,因为当我向它发送一些数据时,我会收到5个以ERR开头的字符:)。
而另一方面,我的线程仍在等待?!:)这就引出了我注意到的另一件事,端口(或通道)并不总是映射到所需的数字。例如,我经常想在端口15上发送一些东西,但在Android上,在端口9上等待的线程收到了数据:)所以我建议,检查哪个端口是真正分配的!你可以使用我发布的代码来实现这一点。还有一点,这里有一个指向channelPicker
函数的链接,当使用普通API时,它会选择通道,如果我没有错的话,内部的一些常量应该表示保留的通道。
我刚刚注意到,我注册端口的代码略有不同,下面是我的操作方法:
Method m = cba.getDeclaredMethod("listenUsingInsecureRfcommOn", int.class);
ss = (BluetoothServerSocket) m.invoke(BluetoothAdapter.getDefaultAdapter(), port);
不管怎样,我知道这可能太晚了,但是,也许将来有人会有类似的问题。