如何将两个设备连接在一起

How can I connect two devices together

我是反应式编程和这个库的新手,我正在尝试编写一个 android 应用程序,该应用程序将能够与具有相同应用程序的其他手机来回发送消息。

我写了一个 BleAdvertiser class 基本上广播服务 UUID,然后我使用 RxAndroidBle 来识别其他设备并尝试连接。看起来我实际上并没有建立连接,但是,没有抛出任何错误。我做错了什么?

在创建时,我会寻找具有相同应用程序的其他手机。打印设备名称和 MAC 地址的日志语句按预期工作,我可以看到我的测试设备。所以我很好。

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    Intent intent = new Intent(this, BluetoothLeService.class);
    startService(intent);

    BleAdvertiser bleAdvertiser = new BleAdvertiser(new AdvertisingPacket(new Date(System.currentTimeMillis())));

    Thread t = new Thread(bleAdvertiser);
    t.start();

    SERVICE = UUID.fromString("e12b9e62-5c03-4ca2-88a5-1034e494f4dc");
    CHARACTERISTIC = UUID.fromString("201274dd-04dc-4ce6-943c-a830df466b33");
    PUUID = ParcelUuid.fromString(SERVICE.toString());

    rxBleClient = RxBleClient.create(this);

    scanSubscription = rxBleClient.scanBleDevices(
            new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_BALANCED).build(),
            new com.polidea.rxandroidble.scan.ScanFilter[]{new ScanFilter.Builder().setServiceUuid(PUUID).build()}
    )
        .subscribe(
            scanResult -> {
                //process new ble device.
                Log.d("Scan Result: ", scanResult.getBleDevice().getMacAddress() + " : " + scanResult.getBleDevice().getName() );
                ConnectToDevice(scanResult.getBleDevice());
            },
            throwable -> {
                Toast.makeText(this,throwable.getMessage(),Toast.LENGTH_LONG ).show();
            }
        );

    ...
}

所以我们尝试连接:

private void ConnectToDevice(RxBleDevice device) {
    device.establishConnection(true)
        .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(CHARACTERISTIC)
            .doOnNext(bytes-> {
                //process read data (convert to message? )
                try {

                    Toast.makeText(this,"stuff happened in what we think is read bytes.",Toast.LENGTH_SHORT).show();
                    ArrayList<TinCanMessage> receivedMessages = (ArrayList<TinCanMessage>) Serializer.deserialize(bytes);

                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            })
            .flatMap(bytes -> {
                Toast.makeText(this,"stuff happened in what we think is write bytes.",Toast.LENGTH_SHORT).show();
                try {
                    return rxBleConnection.createNewLongWriteBuilder()
                        .setCharacteristicUuid(CHARACTERISTIC)
                        .setBytes(Serializer.serialize(new TinCanMessage("New messages will go here.", "kyle")))
                        .build();
                } catch (IOException e) {
                     e.printStackTrace();
                }
                return null;
            })
        )
        .subscribe(
            bytes -> {
                //Written data
                //assign to fragment and update adapter?
                Toast.makeText(this, "stuff happened in the written data section", Toast.LENGTH_SHORT).show();
            },
            throwable -> {
                Toast.makeText(this, throwable.getMessage(), Toast.LENGTH_LONG);
            }
        );
}

感谢所有帮助。

更新

设备实际上正在连接。我已经通过打印到调试器来验证这一点。我以为我遇到了问题,因为我试图验证与未显示的 toast 消息的连接。这是通过 Darkusz Seweryn 的评论发现的,所以我接受了他的回答。我的问题是建立在错误的假设之上的:P

上面的代码看起来不错,似乎没有任何缺陷。

您应该尝试两件事:

  1. 扫描设备外围设备后,您应该停止(取消订阅)扫描。您可以通过在 .subscribe() 之前添加 .take(1).scanBleDevices().
  2. 来自动执行此操作
  3. 您已经使用过RxBleDevice.establishConnection(true)autoConnect=true changes the behaviour of connection。使用 autoConnect=true 连接甚至可以在通话后几分钟建立。您可以使用 autoConnect=false 进行连接,这将在 30 秒内连接(或失败)。