Age*_*opf 2 android bluetooth spp
我有两个不同的蓝牙打印机.Bixolon SPP-R200和Fujitsu FTP-628WSL110.我可以分别连接到每个(使用三星Galaxy SII)打印,断开连接并重新连接就好了.但是,如果我关闭Bixolon并尝试与Fujitsu配对(之前未配对,Bixolon仍然配对),那么当尝试连接到创建的套接字时它会失败.相反的方式.
这是错误消息:
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): Failed to connect to rfcomm socket.
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): java.io.IOException: Service discovery failed
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:406)
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:217)
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): at MyApp.BluetoothConnection.connect(BluetoothConnection.java:171)
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): at MyApp.AbstractBluetoothPrinter.connect(AbstractBluetoothPrinter.java:34)
Run Code Online (Sandbox Code Playgroud)
这是代码,它使连接尝试,在解释的情况下失败的行是btSocket.connect(); - 例外见上文:
/** Is set in connect() */
private BluetoothSocket btSocket = null;
/** Is set prior to connect() */
private BluetoothSocket btDevice;
public boolean connect(){
try {
btSocket = btDevice.createRfcommSocketToServiceRecord("00001101-0000-1000-8000-00805F9B34FB");
if (btDevice.getName().startsWith("FTP")) {
//Special treatment for the fujitsu printer
SystemClock.sleep(1000);
}
} catch (Throwable e) {
LogCat.e(TAG, "Failed to create rfcomm socket.", e);
return false;
}
try {
// Stop Bluetooth discovery if it's going on
BluetoothHandler.cancelDiscovery();
// This fails under the described circumstances
btSocket.connect();
} catch (Throwable e) {
LogCat.e(TAG, "Failed to connect to rfcomm socket.", e);
return false;
}
// Obtain streams etc...
}
Run Code Online (Sandbox Code Playgroud)
我使用相同的 UUID连接到两个设备(但是一次只打开一个设备,它们从未同时打开),SDK API中众所周知的SPP UUID:
00001101-0000-1000-8000-00805F9B34FB
Run Code Online (Sandbox Code Playgroud)
这让我想知道:可能是,我需要为每个设备使用不同的UUID吗?如果是的话有什么想法?
Age*_*opf 10
好几天尝试不同的解决方案后,我现在可以在上述打印机之间切换.由于我不完全确定我的哪些措施是成功的原因,我将列出所有这些,所以有人绊倒这篇文章将有一些关于如何解决他的蓝牙问题的线索.但有一点我很确定:你不需要不同的UUID来连接两台不同的打印机 - 你可以使用相同的UUID(但我只打开其中一台).
我缓存上次打印的设备 - 但不像以前我不再缓存实际的BluetoothDevice,而是我只缓存它的mac地址,可以通过以下方式获得:
BluetoothDevice bluetoothDevice;
//Obtain BluetoothDevice by looking through paired devices or starting discovery
bluetoothDevice.getAddress();
Run Code Online (Sandbox Code Playgroud)
getAddress()返回一个String:设备的硬件地址.我缓存该mac地址,下次用户想要打印时,我将缓存的mac地址与所有配对打印机的mac地址相匹配 - 如果mac地址匹配其中一个,我尝试连接到该打印机.如果失败,我重置我的缓存的mac地址,并尝试通过首先检查我的配对设备,如果其中一个可以连接(如果我可以成功连接,我相应地更新我的缓存的mac地址)找到另一个设备,如果失败我开始寻找其他潜在设备的蓝牙发现.
现在,为了不让任何套接字连接打开我的一个打印机,我的例程如下(我将省略每次调用的try-catches以简化读取):
创建套接字
BluetoothSocket btSocket = btDevice.createRfcommSocketToServiceRecord(MY_UUID);
Run Code Online (Sandbox Code Playgroud)
MY_UUID是指用于连接SPP设备的众所周知的UUID:
00001101-0000-1000-8000-00805F9B34FB
Run Code Online (Sandbox Code Playgroud)
如果套接字创建失败(这很少见,如果它发生,很可能是由于权限不足或蓝牙被禁用/不可用),我们无法继续进行,因为我们需要一个套接字连接.因此,在catch块中,您应该触发disconnect方法(稍后会详细介绍).
连接到创建的套接字
bSocket.connect();
Run Code Online (Sandbox Code Playgroud)
如果连接失败,我们无法继续进行,因为我们需要有效的套接字连接来获取输入和输出流.因此,在catch块中,您应该触发disconnect方法(稍后会详细介绍).
获取输入和输出流
下一步是从套接字获取输入和输出流.我在for循环中执行此操作,该循环运行几次(5次应该足够) - 在每次迭代中我检查是否有输出流,如果没有,我尝试获取它,对于输入流也是如此.在循环结束时,我检查我是否有两个流,如果是,我退出循环(和整个连接方法),如果不是,我继续循环再试一次.通常我在第一次循环迭代中获得两个流,但有时我需要两次或三次迭代才能获得两个流.
如果我在循环声明后到达后面的代码,我显然没有得到我的流或其他错误.此时连接被认为已经失败,我执行我的断开连接代码(清理开放的流和套接字,稍后会详细介绍).
读/写
现在您已连接到目标蓝牙设备,您可以执行读写操作.一旦完成,您应该通过关闭所有流和套接字进行清理,在下一段中将详细介绍:断开连接.切记:如果在读/写操作期间发生异常,请务必触发disconnect方法以清理资源.如果您的打印机需要某种初始化命令,请务必在连接到打印机之后和执行读/写操作之前立即发送.
断开
通常有两种情况应断开:
关闭你的溪流
你要做的第一件事是清理你的流,检查它们,你的输入和输出流,如果它们不是null,关闭它们并将它们设置为null.确保将每个操作(关闭输入流,关闭输出流等)包装到它自己的try-catch中,否则无法进行一次清理(因为引发了异常)将跳过所有其他清理措施.
关闭插座
既然您已确保清理输入流,请继续关闭套接字连接并将其设置为null.
还有一件事:我在disconnect方法的开头和结尾都有一个Thread.sleep.开头的那个长约2.5秒(= 2500毫秒),目的是确保打印机没有其他任何东西(例如挂起的读/写操作或打印机仍在打印等).第二个Thread.sleep在我的disconnect方法的末尾,大约800毫秒长.最后睡眠的原因与我在关闭一个后立即打开一个新套接字时遇到的问题有关.有关详细信息,请参阅此答案.
有问题吗?
如果有人对我的OP或我的答案有任何疑问,请在评论中告诉我,我会尽力回答.
| 归档时间: |
|
| 查看次数: |
3651 次 |
| 最近记录: |