Android 4.3作为蓝牙低功耗服务器:如何启动广告?

19
我正在尝试在Nexus 7上使用4.3中的新BTLE API实现BTLE SERVER。我遇到了几个问题。首先,SDK中没有示例。唯一的示例是客户端示例。其次,文档实际上告诉你做错了事情。它说明必须使用 BluetoothAdapter.getProfileProxy() 并将参数设置为BluetoothProfile.GATT_SERVER来获取BluetoothGattServer对象。这种方法会起作用,但是您将无法将BluetoothGattServerCallback的实现链接到BLE堆栈中(此回调是响应客户端读取和写入请求等的方式)。然而,在发现问题58582后,开发人员指向了新的BluetoothManager.openGattServer()方法,该方法将您的回调作为参数并返回BluetoothGattServer对象。好的,一个问题解决了。
接下来的问题更棘手。 BluetoothGattServer文档说明可以使用此类创建和广播Bluetooth LE服务和特征。创建服务等不是问题,但他们忽略了如何开始广播。我找不到类本身或任何其他类中的方法。
有人知道如何做吗?目前我所能看到的只是使用与客户端相同的方法,但该方法涉及扫描(这不是广告)。所有文档进一步建议BluetoothAdapter.startLeScan()确实仅用于扫描。那么,当我的所有服务、特征和描述符都就绪后,我该如何启动广告呢?

1
我也在寻找这个功能。不幸的是,我不知道这个特性是否被支持,因为文档说Android可以作为中心设备而不是外围设备。无论如何,我没有找到任何官方声明说Android不能作为外围设备。 - edoardotognoni
我认为至少对于BTLE的文档说反了,它可以作为服务器(它有BluetoothGattServer类和构建服务、特征和描述符的能力!)实际上确实如此。我知道经典蓝牙只能作为客户端。 - Brian Reinhold
我在想为什么谷歌没有决定给他们的Android设备提供外围功能。自从iOS 6以来,苹果就提供了这个功能。让我们等待其他版本的发布,希望能看到这个功能的出现 :( - edoardotognoni
4个回答

17
据我了解,Android实现只能作为中心设备,而不能作为外围设备。在蓝牙低能耗中,只有外围设备可以进行广告推送。中心设备可以扫描外围设备的广告,并以响应广告的方式发送连接请求,从而与外围设备建立连接。
在BLE中,存在"中心/外围"和"服务器/客户端"两个概念:
- 中心/外围是与网络架构相关的,中心是星型拓扑结构的中心,可以连接一个或多个外围设备,通常是手机、平板电脑或计算机。外围设备一次只能连接一个中心。 - 服务器/客户端(GATT服务器/客户端)是一个更高级别的概念,与设备中存储的数据及其可能通过连接进行通信有关。中心和外围设备都可以实现GATT服务器和GATT客户端,但不必同时具备。
因此来回答你的问题:你无法调用广告,必须开始扫描外围设备才能连接其中一个或多个。
希望这能帮到你。

2
那么,Android BluetoothGattServer类中的这个语句是不正确的吗?蓝牙GATT配置文件服务器角色的公共API。该类提供了蓝牙GATT服务器角色功能,允许应用程序创建和广告蓝牙智能服务和特征。BluetoothGattServer是通过IPC控制蓝牙服务的代理对象。使用getProfileProxy(Context, BluetoothProfile.ServiceListener, int)获取BluetoothGatt代理对象。 - Brian Reinhold
总之,你给出的答案不是我想听到的,希望它不是真的,但可能是他们在文档中误导了我们(请注意,同样的文档也提供了获取对象的错误方式!)。 - Brian Reinhold
我认为他们在文档编写方面可能有些匆忙。外围设备可以将其服务信息放入广告数据包中,即宣传其服务。对于任何外围设备来说,要想知道中央实现了哪些服务,它将在连接后执行服务发现过程。有关GATT和服务的更多信息,请在bluetooth.org上注册并下载核心规范V4.0,并查看第3卷G部分。 - oyhovd
2
很不幸,我收到了谷歌的消息,你是正确的。文档选词非常不当,显然需要改进。我浪费了两天时间配置服务、特性等,为一个我无法使用的设备。正是“广告”这个词让我困惑了。我们已经实现了在PC上运行的BTLE堆栈,如果有这个堆栈可以用来测试我们的客户端就太好了。现在我们只能做相反的事情。 - Brian Reinhold

12

您需要API 21级。

import android.bluetooth.le;
...
...
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter myBluetoothAdapter = bluetoothManager.getAdapter();
BluetoothLeAdvertiser myBluetoothLeAdvertiser =  myBluetoothAdapter.getBluetoothLeAdvertiser ();
myBluetoothLeAdvertiser.startAdvertising (AdvertiseSettings settings, AdvertiseData advertiseData, AdvertiseCallback callback);

有用的链接是:https://developer.android.com/about/versions/android-5.0.html


而且硬件也支持。可能只有N6和N9。 - IronBlossom

2
似乎 getProfileProxy 不响应 GATTGATT_SERVER 请求。API 建议支持广告,但目前尚未实现任何代码。(Android 问题跟踪器)
当 NFC 首次推出时,也发布了同样半成品的 API,随后谷歌逐步添加了更全面的功能。

1
据我所见,BLE广播能力(又称外围模式)将在即将发布的Kitkat 4.4.3版本中加入Android。预计下周发布,但变更日志已经意外地泄露,可以在Google缓存或第2554行这里看到:外围模式(3/4):添加外围模式API
我猜我们很快就会知道更多。

根据您提供的链接,我不禁注意到很多这样的实例:DO NOT MERGE BLE peripheral mode。这可能意味着它们还没有准备好进行外设模式。 - Bamaco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接