Articles of bluetooth lowenergy

如何在BLE中解决onClientConnectionState() – status = 22 clientIf = 7的错误

我有一个Android应用程序,用于连接蓝牙低功耗 (BLE)和我的手机。 该应用程序在几乎手机中运行良好,如Galaxy S5(Android 5.0.1),Galaxy S6(Android 6.0)。 但是,它在Galaxy Note 3(Android 5.0.1)中存在一个关键问题。 当我调用connect()函数,然后调用readCharacteristic() ,它返回错误: onClientConnectionState() – status = 22 clientIf = 7 我调用connect函数大约2秒后发生错误。 我查找了一些解决方案,比如在调用readCharacteristic()之前做出延迟,但它无法解决。 你能解决我的问题吗? 谢谢大家。 这是我的代码: private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { mBluetoothGatt.discoverServices(); } else if (newState == […]

Android 4.3 BTLE作为服务器:如何开始广告?

我试图在4.3中使用新的BTLE API在Nexus 7上实现BTLE SERVER。 我遇到了几个问题。 首先,SDK没有示例。 唯一的例子是客户端。 其次,文档实际上告诉你做错了。 它声明必须使用BluetoothAdapter.getProfileProxy() with a BluetoothProfile.GATT_SERVER参数的BluetoothAdapter.getProfileProxy() with a BluetoothProfile.GATT_SERVER来获取BluetoothGattServer对象。 这种方法可行,但是无法将BluetoothGattServerCallback一个实现链接到BLE堆栈。 (此回调是人们如何响应客户端读取和写入请求等。)然而,在问题58582上遇到问题后,开发人员指出了新的BluetoothManager.openGattServer()方法,该方法将您的回调作为参数并返回BluetoothGattServer对象。 好吧,一个问题解决了。 下一个问题更成问题。 BluetoothGattServer文档声明可以使用此类创建和通告蓝牙LE服务和特性。 创建服务等不是问题,但他们忽略了如何开始做广告。 类本身或我可以find的任何其他类中没有方法。 有谁知道如何做到这一点? 目前我所能看到的是使用客户端使用的相同方法,但这种方法涉及扫描(不是广告)。 所有文档进一步表明BluetoothAdapter.startLeScan()确实只是用于扫描。 那么一旦我的所有服务,特征和描述符到位,我该如何调用广告?

基于RSSI估计信标接近度/距离 – 蓝牙LE

我有一个简单的iOS应用程序,显示它使用诸如“立即”,“近”等expression式检测到的蓝牙LE信标的接近度。我需要在Android上编写类似的东西。 我已经按照Android开发人员的教程进行了操作 ,我能够列出检测到的设备,现在想要估算距离/接近度 – 这就是它成为问题的地方。 根据这个SO线程,它只是一些数学计算。 但是,它们要求我提供txPower值。 根据Dave Smith的本教程 (以及与此蓝牙SIG声明的交叉引用),它应该由信标设备广播为types0x0A的“AD结构”。 所以我所做的是解析AD结构并查找与该types匹配的有效负载。 问题:我有4个信标 – 2个estimotes和2个appflares。 estimotes根本不播放txPower,appflares将它们广播为0。 这里有什么我想念的吗? iOS应用程序似乎没有任何问题处理它,但使用iOS SDK它在幕后做,所以我不知道如何产生完全相同或类似的行为。 还有其他方法可以解决我的问题吗? 如果您想查看我用来解析AD结构的代码,可以从前面提到的Dave Smith的github中获取,可以在这里find。 我对该类所做的唯一更改是添加以下方法: public byte[] getData() { return mData; } 这就是我处理扫描回调的方法: // Prepare the callback for BLE device scan this.leScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { if […]

BluetoothLeAdvertiser可以在Android 5.0的Nexus 5上运行吗?

将我的Nexus 5闪存到Android 5.0预览版本hammerhead-lpx13d后,操作系统报告它不再支持蓝牙LE广告。 如果你打电话: ((BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE)) .getAdapter().getBluetoothLeAdvertiser() 始终返回null。 另外,新方法: ((BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE)) .getAdapter().isMultipleAdvertisementSupported() 总是返回false 第一种用于在6月份返回Nexus 5的第一个Android L预览版本上的有效对象的方法。 闪烁最新更新后,它不再这样做了。 有人看到了吗? 编辑:至少有一个人在此处复制了这个问题: https : //code.google.com/p/android-developer-preview/issues/detail?id = 1570

蓝牙LE ScanFilters无法在Android M上运行

以下代码适用于运行Android 5.1.1(Build LMY48M)的Nexus 9,但不适用于运行Android 6.0的Nexus 9(Build MPA44l) List filters = new ArrayList(); ScanSettings settings = (new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)).build(); ScanFilter.Builder builder = new ScanFilter.Builder(); builder.setManufacturerData((int) 0x0118, new byte[]{(byte) 0xbe, (byte) 0xac}, new byte[]{(byte) 0xff, (byte)0xff}); ScanFilter scanFilter = builder.build(); filters.add(scanFilter); mBluetoothLeScanner.startScan(filters, settings, new ScanCallback() { … }); 在Android 5.x上,当看到与扫描filter匹配的制造商广告时,上述代码产生回调。 (参见下面的示例Logcat输出。)在带有MPA44l的Nexus 9上,没有收到回调。 如果您注释掉扫描filter,则会在Nexus 9上成功收到回叫。 09-22 00:07:28.050 1748-1796/org.altbeacon.beaconreference D/BluetoothLeScanner﹕ […]

Android上的蓝牙低功耗专用与公共地址

蓝牙低功耗设备由其地址唯一标识(在Android API中,他们将其称为MAC地址,并将其表示为冒号分隔的hex值,例如11:aa:22:bb:33:cc)。 但要唯一识别BLE地址,您需要知道它是公共地址还是私人地址。 实质上,识别地址需要49位,而不是48位。 随机地址可以是静态随机地址,不可解析私有地址或可解析私有地址,这些types在两个最重要的字节(分别为11,00和10)中由位模式分隔。 但是我没有看到只要通过查看地址中的48位就可以将公共地址和随机地址分开的任何地方。 那么这在Android API中如何运作? 当他们不知道您指定的地址是公开的还是随机的时,他们如何知道要连接的设备? 有问题的API例如是getRemoteDevice函数。 它说: Valid Bluetooth hardware addresses must be upper case, in a format such as “00:11:22:33:AA:BB”. The helper checkBluetoothAddress(String) is available to validate a Bluetooth address. A BluetoothDevice will always be returned for a valid hardware address, even if this adapter has never seen that device. […]

如何检测BLE设备何时不在范围内?

我使用LeScanCallback(不能使用更新的扫描方法,因为我正在开发api 18.并不重要,因为android 5.0+ apis也不提供此function)来检测何时检测到附近的BLE设备: private BluetoothAdapter.LeScanCallback bleCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice bluetoothDevice, int i, byte[] bytes) { discoveredDevices.add(bluetoothDevice); } }; 我没有与设备配对或连接,因为这不是必需的,我只是想看看附近有哪些设备。 我正在尝试提供一项服务,每隔5分钟左右,就会调用一个网络服务器来更新当时附近的设备。 棘手的部分是Android设备将移动,所以现在附近的蓝牙设备可能不会在5分钟内。 在这种情况下,我需要从discoveredDevices删除它。 理想情况下,我希望在蓝牙设备处于范围之前接收回调,但现在不再。 但是这个回调不存在。 (我知道android.bluetooth.device.action.ACL_CONNECTED和android.bluetooth.device.action.ACL_DISCONNECTED广播,但是当你连接到蓝牙设备时,这些是我不想要的。) 一个选项是每隔5分钟进行一次新扫描,但是你无法判断所有附近的设备何时被发现,所以你必须进行定时扫描,例如扫描5秒,然后将收集的数据发送到网络服务。 这听起来很脏并且有风险,因为您无法确定所有附近的设备是否在规定的时间内被发现,因此我非常希望避免这样做。 还有另一种方法吗? 编辑 一些设备不断报告附近蓝牙设备的发现,即使它们之前已经被发现过。 如果该function是通用的,我可以解决我的问题,但这是特定于设备的。 例如,我的手机的蓝牙适配器仅发现附近的设备一次。 我测试过的其他一些设备不断报告相同的附近设备,但不是所有设备都这样,所以我不能不依赖它。

Android:BLE如何读取多个特征?

用于读取某些特征的Android BLE API方法本质上是异步的,当您请求某些值时,将调用您的GATT回调方法。 如果您请求多个读取特征值,它只会丢弃其他值,直到它不接受第一个请求为止。 我不明白是否这样,为什么他们制作方法Async。 如果有人知道我们应该采用哪种设计模式来解决这个问题,请分享。 如果您想阅读一些特征,那么您必须要求它。 // new value available will be notified in Callback Object mBluetoothGatt.readCharacteristic(ch); GATT回调 public void onCharacteristicRead(BluetoothGatt gatt, android.bluetooth.BluetoothGattCharacteristic characteristic, int status) 可能的解决方案#1 https://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained 任何人都可以解释如何使用它。 我认为这将有助于这种情况,但我仍然在寻找如何使用它。 可能的解决方案#2 https://code.google.com/p/mobility-rpc/source/browse/mobility-rpc/trunk/src/main/java/com/googlecode/mobilityrpc/session/impl/MobilitySessionImpl.java#395 可能的解决方案#3 http://tutorials.jenkov.com/java-util-concurrent/synchronousqueue.html 可能的解决方案#4 http://examples.javacodegeeks.com/core-java/util/concurrent/synchronous-queue-example-to-execute-commands/ 可能的解决方案#5 https://stackoverflow.com/a/15816566/185022 更新 我已经成功地使用Queue更好的SynchronousQueue,但我会在测试后分享我的最终解决方案。 指定超时,否则它将被卡住或者如果您请求读取不支持读取操作的特性。 您可以看到哪些特征是可读写的, 请参阅此post

Android BLE,读写特性

我目前正在开发Android BLE,并且在Android BLE堆栈中遇到很多问题.. 我的开发工具是三星Galaxy J和Android 4.3。 我想知道如何从BLE中读取特征并写入特征(就像我validation了我收到的数据,然后我使用BLE发送另一个数据) 我有严重的问题了解Android BLE回调如何工作,我不明白这5个function……而且手册不清楚,任何人都可以用简单的forms解释好的灵魂??? onCharacteristicWrite onCharacteristicRead onCharacteristicChanged onDescriptorRead onDescriptorWrite 我目前的情况是,我设法读取onCharacteristicChanged()回调中的数据,然后我validation了收到的数据我试图通过使用发送数据 characteristics.setValue(data) gatt.writeCharacteristic(characteristics) 但是,Android BLE堆栈没有调用onCharacteristicsWrite(),事实上,Android只是挂在那里.. 我尝试谷歌关于Android BLE,没有太多的信息,只有一堆抱怨BLE堆栈是多么不稳定……

Android 4.3:BLE:startLeScan()的过滤行为

我正在开发一个蓝牙传感器设备,我需要对其进行一对多的数据广播。 根据规范,外设可能只有一个主机,由于我设计的芯片和堆栈的限制,主机只能有三个从机。 据我所知,Android无论如何都不能成为BLE奴隶,因此将我的设备作为主人不是一种选择。 BT4规范和制造商文档都讨论了另一种操作模式,称为广播模式。 在广播模式中,永远不会建立连接,并且应用数据作为广告包的一部分被发送。 这完全符合我的需求,因为许多Android / iOS手机可以同时扫描每个数据包。 广告数据包以突发方式多次传输,因此我怀疑数据接收最可靠。 如果数据包在此处丢失,则可以容忍。 这有趣的是,我希望这些数据包携带实时传感器数据,以10-20Hz的速率更新。 从我在网上find的例子来看,这种模式下的BLE主要用于“iBeacon”types的实现,它们在那里广播静态数据。 我找不到有关如何在Android堆栈中过滤广告数据包的任何信息。 它可能是每个蓝牙硬件地址返回一个结果,或者它可能是地址和数据的唯一组合。 第二个选项适用于此应用程序。 如果启动和停止扫描重置filter,我也可以做一些工作。 Android文档没有提及扫描方法中的设备过滤如何工作。 我已经能够在网上find一个试图解决同样问题的post,它有一个未解决的响应: BLE:在扫描过程中多次发现同一个外设 。 在iOS中,我的同事通知我,有一个参数可以传递给扫描function,使其成为可能。 我试图从Android源代码中的startLeScan()调用回溯代码,但代码非常复杂,并且使用抽象使得很难识别包含它的对象的实现。 我得到的最远的是从BluetoothManagerService类方法getBluetoothGatt()返回的IBluetoothGatt对象。 该对象接收开始扫描的请求。 它正在github上的当前版本上的BluetoothManagerService.java的第790行进行实例化。 该对象是从消息的结果转换而来的,所以我怀疑结果可能是电话/驱动程序特定的。 能够进一步追踪它是我的专业知识。 我想解决的另一个问题是可以快速打开和关闭扫描。 扫描是一项功耗密集型操作,但数据广播将在相当精确的实时计时器上定期发生。 因此,如果可以打开和关闭扫描,这将是一个很好的优化,使得广播和扫描同步,扫描仪关闭其他90%以上的时间。 这可能需要通过实验进行测试。 我还在进行可行性研究,看看我们的Android配件是否可行。 我目前的手机还没有运行4.3版,所以我无法通过实验测试/黑客攻击。