blob: a468968826c415c2fb309ec816bfcda07833416c [file] [log] [blame]
<html devsite><head>
<title>蓝牙低功耗公告功能</title>
<meta name="project_path" value="/_project.yaml"/>
<meta name="book_path" value="/_book.yaml"/>
</head>
<body>
<!--
Copyright 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>
蓝牙低功耗 (BLE) 大部分时间处于睡眠模式,以节省电量。它只会在进行公告和进行短促连接时唤醒,因此这些公告会影响电量消耗和数据传输带宽。
</p>
<h2 id="bluetooth-5-advertising-extension">蓝牙 5 公告功能扩展</h2>
<p>Android 8.0 支持蓝牙 5,该版本针对 BLE 对广播功能进行了改进,并提供了灵活的数据公告功能。蓝牙 5 支持 BLE 物理层 (PHY),PHY 不仅保留了蓝牙 4.2 的耗电量少这一优点,还允许用户选择更大的带宽或范围。如需更多信息,请参阅<a href="https://www.bluetooth.com/specifications/adopted-specifications">蓝牙 5 核心规格</a>
</p>
<h3 id="implementation">实现</h3>
<p>
蓝牙 5 的新功能可自动适用于运行 Android 8.0 且具有兼容蓝牙控制器的设备。您可以使用这些 <code><a href="https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html">
BluetoothAdapter</a></code> 方法来检查设备是否支持蓝牙 5 的功能:
</p>
<ul>
<li><code>isLe2MPhySupported()</code></li>
<li><code>isLeCodedPhySupported()</code></li>
<li><code>isLeExtendedAdvertisingSupported()</code></li>
<li><code>isLePeriodicAdvertisingSupported()</code></li>
</ul>
<p>
要停用公告功能,请联系蓝牙芯片供应商来停用芯片组支持。
</p>
<p>
蓝牙 PHY 是互斥的,并且每个 PHY 的行为均由蓝牙 SIG 预先定义。默认情况下,Android 8.0 使用蓝牙 4.2 的蓝牙 LE 1M PHY。<code><a href="https://developer.android.com/reference/android/bluetooth/le/package-summary.html">
android.bluetooth.le</a></code> 程序包通过以下 API 提供蓝牙 5 的公告功能:
</p>
<ul>
<li><code>AdvertisingSet</code></li>
<li><code>AdvertisingSetCallback</code></li>
<li><code>AdvertisingSetParameters</code></li>
<li><code>PeriodicAdvertisingParameters</code></li>
</ul>
<p>
通过使用 <code><a href="https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser.html">
android.bluetooth.le.BluetoothLeAdvertiser</a></code> 中的 <code><a href="https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser.html#startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters,
android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData,
android.bluetooth.le.PeriodicAdvertisingParameters,
android.bluetooth.le.AdvertiseData,
android.bluetooth.le.AdvertisingSetCallback)">
startAdvertisingSet()</a></code> 方法,可以创建 <code><a href="https://developer.android.com/reference/android/bluetooth/le/AdvertisingSet.html">
AdvertisingSet</a></code> 来修改蓝牙公告设置。即使对蓝牙 5 或其公告功能的支持被停用,API 功能也可以应用于 LE 1M PHY。
</p>
<h4 id="examples">示例</h4>
<p>
该示例应用使用蓝牙 LE 1M PHY 进行公告:
</p>
<pre class="prettyprint">
// Start legacy advertising. Works for devices with 5.x controllers,
and devices that support multi-advertising.
void example1() {
BluetoothLeAdvertiser advertiser =
BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
AdvertisingSetParameters parameters = (new AdvertisingSetParameters.Builder())
.setLegacyMode(true) // True by default, but set here as a reminder.
.setConnectable(true)
.setInterval(AdvertisingSetParameters.INTERVAL_HIGH)
.setTxPowerLevel(AdvertisingSetParameters.TX_POWER_MEDIUM)
.build();
AdvertiseData data = (new AdvertiseData.Builder()).setIncludeDeviceName(true).build();
AdvertisingSetCallback callback = new AdvertisingSetCallback() {
@Override
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
Log.i(LOG_TAG, "onAdvertisingSetStarted(): txPower:" + txPower + " , status: "
+ status);
currentAdvertisingSet = advertisingSet;
}
@Override
public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {
Log.i(LOG_TAG, "onAdvertisingDataSet() :status:" + status);
}
@Override
public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {
Log.i(LOG_TAG, "onScanResponseDataSet(): status:" + status);
}
@Override
public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
Log.i(LOG_TAG, "onAdvertisingSetStopped():");
}
};
advertiser.startAdvertisingSet(parameters, data, null, null, null, callback);
// After onAdvertisingSetStarted callback is called, you can modify the
// advertising data and scan response data:
currentAdvertisingSet.setAdvertisingData(new AdvertiseData.Builder().
setIncludeDeviceName(true).setIncludeTxPowerLevel(true).build());
// Wait for onAdvertisingDataSet callback...
currentAdvertisingSet.setScanResponseData(new
AdvertiseData.Builder().addServiceUuid(new ParcelUuid(UUID.randomUUID())).build());
// Wait for onScanResponseDataSet callback...
// When done with the advertising:
advertiser.stopAdvertisingSet(callback);
}</pre>
<p>
该示例应用使用 BLE 2M PHY 进行公告。该应用会首先检查设备是否支持要使用的功能。如果设备支持公告功能,该应用会将 BLE 2M PHY 配置为主 PHY。当 2M PHY 处于活动状态时,公告功能不支持蓝牙 4.x 控制器,因此 <code>setLegacyMode</code> 会被设为 <code>false</code>。该示例可在进行公告时修改参数,也可暂停公告。
</p>
<pre class="prettyprint">void example2() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
BluetoothLeAdvertiser advertiser =
BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
// Check if all features are supported
if (!adapter.isLe2MPhySupported()) {
Log.e(LOG_TAG, "2M PHY not supported!");
return;
}
if (!adapter.isLeExtendedAdvertisingSupported()) {
Log.e(LOG_TAG, "LE Extended Advertising not supported!");
return;
}
int maxDataLength = adapter.getLeMaximumAdvertisingDataLength();
AdvertisingSetParameters.Builder parameters = (new AdvertisingSetParameters.Builder())
.setLegacyMode(false)
.setInterval(AdvertisingSetParameters.INTERVAL_HIGH)
.setTxPowerLevel(AdvertisingSetParameters.TX_POWER_MEDIUM)
.setPrimaryPhy(BluetoothDevice.PHY_LE_2M)
.setSecondaryPhy(BluetoothDevice.PHY_LE_2M);
AdvertiseData data = (new AdvertiseData.Builder()).addServiceData(new
ParcelUuid(UUID.randomUUID()),
"You should be able to fit large amounts of data up to maxDataLength. This goes
up to 1650 bytes. For legacy advertising this would not
work".getBytes()).build();
AdvertisingSetCallback callback = new AdvertisingSetCallback() {
@Override
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
Log.i(LOG_TAG, "onAdvertisingSetStarted(): txPower:" + txPower + " , status: "
+ status);
currentAdvertisingSet = advertisingSet;
}
@Override
public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
Log.i(LOG_TAG, "onAdvertisingSetStopped():");
}
};
advertiser.startAdvertisingSet(parameters.build(), data, null, null, null, callback);
// After the set starts, you can modify the data and parameters of currentAdvertisingSet.
currentAdvertisingSet.setAdvertisingData((new
AdvertiseData.Builder()).addServiceData(new ParcelUuid(UUID.randomUUID()),
"Without disabling the advertiser first, you can set the data, if new data is
less than 251 bytes long.".getBytes()).build());
// Wait for onAdvertisingDataSet callback...
// Can also stop and restart the advertising
currentAdvertisingSet.enableAdvertising(false, 0, 0);
// Wait for onAdvertisingEnabled callback...
currentAdvertisingSet.enableAdvertising(true, 0, 0);
// Wait for onAdvertisingEnabled callback...
// Or modify the parameters - i.e. lower the tx power
currentAdvertisingSet.enableAdvertising(false, 0, 0);
// Wait for onAdvertisingEnabled callback...
currentAdvertisingSet.setAdvertisingParameters(parameters.setTxPowerLevel
(AdvertisingSetParameters.TX_POWER_LOW).build());
// Wait for onAdvertisingParametersUpdated callback...
currentAdvertisingSet.enableAdvertising(true, 0, 0);
// Wait for onAdvertisingEnabled callback...
// When done with the advertising:
advertiser.stopAdvertisingSet(callback);
}</pre>
<h3 id="verification">验证</h3>
<p>运行适用的<a href="https://www.bluetooth.com/develop-with-bluetooth/test-tools">蓝牙产品测试</a>,以验证设备是否与蓝牙 5 兼容。
</p>
<p>
AOSP 包含 Android 通讯测试套件 (ACTS),其中包括针对蓝牙 5 的测试。您可以在以下位置找到针对蓝牙 5 的 ACTS 测试:<code><a href="https://android.googlesource.com/platform/tools/test/connectivity/+/master/acts/tests/google/ble/bt5/">
tools/test/connectivity/acts/tests/google/ble/bt5</a></code>
</p>
</body></html>