代码之家  ›  专栏  ›  技术社区  ›  Kyle

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

  •  1
  • Kyle  · 技术社区  · 7 年前

    我不熟悉反应式编程和这个库,我正在尝试编写一个android应用程序,它可以与其他拥有相同应用程序的手机来回发送消息。

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

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

    @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 回复  |  直到 4 年前
        1
  •  2
  •   Dariusz Seweryn    7 年前

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

    您应该尝试两件事:

    1. 扫描完设备外围设备后,应停止(取消订阅)扫描。您可以通过添加 .take(1) 就在之前 .subscribe() .scanBleDevices() .
    2. 您已使用 RxBleDevice.establishConnection(true) . 这个 autoConnect=true changes the behaviour of connection . 具有 自动连接=真 即使在通话后许多分钟,也可能建立连接。您可以连接 autoConnect=false 只需30秒即可连接(或失败)。