好的,我是新手,但我可以尽力提供帮助。这是我的经验,我设法使用反射连接两个设备。我的Android手机正在使用方法接收数据listenUsingInsecureRfcommOn
,而其他设备是通信的主设备,并通过 BT SPP 发送数据。我在使用此方法时遇到了问题,因为它没有生成可见的 SDP 记录,因此我无法使用其他设备检测到它。因此,我使用 Bluecove 和 Java SE 制作了小型嗅探器,尝试连接到给定范围内的每个端口。这是代码:
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 = %d\n", 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 已被占用,因为当我向其发送一些数据时,我会收到以 ERR 开头的 5 个字符:)。
另一方面,我的线程仍在等待?! :)
这让我们注意到我注意到的另一件事,端口(或通道)并不总是映射到所需的数字。例如,对我来说,经常发生这样的情况:我想在端口 15 上发送一些东西,但在 Android 上,等待端口 9 的线程收到了数据:)
所以我建议,检查哪个端口真正被分配了!
您可以使用我发布的代码来实现这一点。
还有一件事,这是一个link to channelPicker
函数,当使用普通API时选择通道,如果我没有记错的话,里面的一些常量应该代表保留通道。
我刚刚注意到一些事情,我的注册端口的代码略有不同,这是我的做法:
Method m = cba.getDeclaredMethod("listenUsingInsecureRfcommOn", int.class);
ss = (BluetoothServerSocket) m.invoke(BluetoothAdapter.getDefaultAdapter(), port);
无论如何,我知道这可能为时已晚,但是,也许将来有人有类似的问题。