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

时间:2018-01-04 20:35:17

标签: rxandroidble

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

我已经编写了一个基本上广播服务UUID的BleAdvertiser类,然后使用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 个答案:

答案 0 :(得分:2)

上面的代码看起来很好,因为它似乎没有任何缺陷。

你应该尝试两件事:

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