我正在写一个应用程序,扫描蓝牙信标时,应用程序是在前景和背景。我已经弄清楚了前台部分,但我不知道如何处理后台部分,特别是在Android8.0和以上版本中,系统不允许应用程序在后台运行更长时间的15分钟。
该应用程序需要扫描信标,并获取他们的mac地址和UUID。此外,它应该得到扫描响应,因为有一些信息,我需要解码和保存。我已经使用指南这里实现了前景扫描使用BluetoothLeScanner。至于背景,我试着将扫描模式更改为LOW_POWER,但是操作系统在15分钟后就会杀死这个应用程序。请注意,我不希望前台服务有一个不断的通知,我很好的扫描只运行间隔约15分钟。
许多人建议使用安卓灯塔库,但我找不到我们使用的信标类型所需的beaconLayout,KontaktBeaconProBP16-3,所以信标库没有检测到它们。
我需要的信息,从信标,包括唯一的ID和电池百分比。有关它们在扫描响应中的位置的详细信息,请参见这里。
我希望您能帮助我编写代码,以便在6.0或更高版本的Android版本上搜索信标,或者帮助使用灯塔库和上面提到的信标。
编辑:唯一的ID &来自扫描响应的蓝牙
当我使用BLEScanner扫描信标时,我可以使用ScanResult::getScanRecord()来获取scanRecord对象。然后,我使用getServiceData()方法获得一个字节数组,其前4个字节表示ASCII中唯一的ID,接下来的两个字节是ASCII中的固件版本,最后一个字节是十六进制中的电池百分比。我甚至确认了电池水平与官方的Kontakt应用程序,所以我相信它是正确的。
当我使用灯塔库时,我找不到一种简单的方法来获得扫描响应的解析版本。相反,我必须使用一个NonBeaconLeScanCallback来获取字节数组。然后,字节数组被证明是
[2, 1, 6, 26, -1, 76, 0, 2, 21, -9, -126, 109, -90, 79, -94, 78, -104, -128, 36, -68, 91, 113, -32, -119, 62, -91, 68, 124, 56, -77, 8, 9, 75, 111, 110, 116, 97, 107, 116, 2, 10, -12, 10, 22, 13, -48, 68, 106, 69, 77, 52, 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0].索引46-49中的字节似乎表示了ASCII中唯一的id,在本例中是"DjEM“。此外,索引52处的字节是以十进制为单位的电池百分比;在这种情况下,是68。
似乎通过使用BLE扫描仪,我可以在解析唯一的ID和电池方面节省很多麻烦。然而,要可靠地实现背景扫描要困难得多。因此,是否有一种方法可以将两者结合起来,并获得培根库来解析唯一的ID和电池百分比?
EDIT2:不识别我的信标时的信标库消息
尽管我同时使用iBeacon和EddyStone信标布局,但信标库仍然无法检测到我的信标。它在logcat中打印以下内容:
processing pdu type 16: 0201060d166afe0206010a64f456425a4d08094b6f6e74616b74000000000000000000000000000000000000000000000000000000000000000000000000 with startIndex: 5, endIndex: 16
This is not a matching Beacon advertisement. (Was expecting 02 15. The bytes I see are: 0201060d166afe0206010a64f456425a4d08094b6f6e74616b74000000000000000000000000000000000000000000000000000000000000000000000000
Ignoring pdu type 01提前谢谢。
发布于 2019-04-02 22:23:31
根据链接的Kontakt.io文档,扫描响应中也有电池电平。(注意:当您检测到信标数据包时,扫描响应并不总是可用的,但它通常是可用的--它由Android操作系统提供,并在接收到扫描响应时与扫描数据合并。)在原始的Android扫描结果bye数组中,扫描响应被简单地加到常规扫描数据的末尾。
当使用Android时,扫描响应也是可用的,Android操作系统接受扫描响应并将其存储在BluetoothDevice#name字段中。(见这里。安卓信标库在解析信标时,将该字段复制到Beacon#name字段中。因此,如果您可以解析信标,并且设备检测到扫描响应,则信息将作为字符串提供给您。
这里有两个障碍:
processing pdu type 16: 0201060d166afe0206010a64f456425a4d08094b6f6e74616b74000000000000000000000000000000000000000000000000000000000000000000000000 with startIndex: 5, endIndex: 16 This is not a matching Beacon advertisement.不对应于iBeacon或Eddystone。这似乎是某种专利的16位GATT服务广告(广告类型0x16).它的16位服务UUID为0x0102,这与标准或自定义 16位UUID的蓝牙SIG列表中没有对应。你的猜测和我的一样好!发布于 2019-03-31 23:37:59
您不能简单地通过扫描广告来读取Kontakt.io信标的电池级别。您必须使用GATT上的服务连接到它(下面将有更多的信息)。
对于背景和前景中的一般扫描,您当然可以使用。您可能希望使用iBeacon布局:
mBeaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));但是,虽然上面会检测到你的信标,但它不会告诉你电池的水平。这是因为Kontakt没有宣传它的电池级别。要获得它,您必须使用service = 0x1805分别连接到GATT服务,然后读取具有特征UUID = 0x2a19的特性的值。这将返回一个介于0-100之间的值,指示电池的百分比水平.
您可以在Kontakt.io的“其他BLE扫描器”部分这里中看到如何访问它的详细信息。
好的,这并没有告诉您如何编写代码来读取这个值。要做到这一点,您需要学习蓝牙LE GATT编程的基础知识,这需要一点学习。一个很好的起点是这里。,您需要编写几个步骤:
String macAddress = beacon.getBluetoothAddress();中的设备MAC地址)bluetoothAdapter.getRemoteDevice(macAddress).connectGatt(...)连接到该设备。所有这些都可能被放到一个预定的作业中,每15分钟运行一次,使用附近信标的蓝牙MAC地址字符串的存储副本。
我知道这可不容易我知道。我希望我能给你几行代码,以获得电池的水平,但不幸的是,它不能那样工作。欢迎来到蓝牙世界关贸总协定编程!
https://stackoverflow.com/questions/55445707
复制相似问题