O Bluetooth de baixa energia (BLE) economiza energia permanecendo no modo de espera na maior parte do tempo. Ele só é ativado para fazer anúncios e conexões curtas, então os anúncios afetam o consumo de energia e a largura de banda de transferência de dados.
Extensão de publicidade Bluetooth 5
O Android 8.0 é compatível com o Bluetooth 5, que oferece melhorias de transmissão e anúncios de dados flexíveis para BLE. O Bluetooth 5 é compatível com camadas físicas (PHYs, na sigla em inglês) de BLE que mantêm o consumo de energia reduzido do Bluetooth 4.2 e permitem que os usuários escolham entre maior largura de banda ou alcance. Confira mais informações nas especificações principais do Bluetooth 5 (link em inglês).
Implementação
Os novos recursos do Bluetooth 5 estão disponíveis automaticamente para dispositivos com Android 8.0 e controladores Bluetooth compatíveis. Use estes métodos BluetoothAdapter
para verificar se um dispositivo é compatível com os recursos do Bluetooth 5:
isLe2MPhySupported()
isLeCodedPhySupported()
isLeExtendedAdvertisingSupported()
isLePeriodicAdvertisingSupported()
Para desativar os recursos de publicidade, trabalhe com o fornecedor do chip Bluetooth para desativar o suporte ao chipset.
As PHYs do Bluetooth são exclusivas umas das outras, e o comportamento de cada PHY é
predefinido pelo Bluetooth SIG. Por padrão, o Android 8.0 usa Bluetooth LE 1M
PHY, do Bluetooth 4.2. O pacote android.bluetooth.le
expõe os
recursos de publicidade do Bluetooth 5 pelas seguintes APIs:
AdvertisingSet
AdvertisingSetCallback
AdvertisingSetParameters
PeriodicAdvertisingParameters
Crie um AdvertisingSet
para modificar as configurações de anúncios do Bluetooth usando o método startAdvertisingSet()
em android.bluetooth.le.BluetoothLeAdvertiser
. Mesmo que o suporte para Bluetooth 5 ou os recursos de publicidade dele estejam desativados, os recursos da API também podem ser aplicados ao LE 1M PHY.
Exemplos
Este app de exemplo usa o PHY de 1M do Bluetooth LE para publicidade:
// 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);
}
Este app de exemplo usa a camada física BLE 2M para publicidade. Primeiro, o app verifica se o dispositivo é compatível com os recursos usados. Se os recursos de publicidade forem compatíveis, o app vai configurar o BLE 2M PHY como o PHY principal. Enquanto o PHY de 2M
estiver ativo, a publicidade não será compatível com controladores Bluetooth 4.x. Portanto, setLegacyMode
será definido como false
. Este exemplo modifica parâmetros durante a publicidade e também pausa o anúncio.
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_1M)
.setSecondaryPhy(BluetoothDevice.PHY_LE_2M);
AdvertiseData data = (new AdvertiseData.Builder()).addServiceData(new
ParcelUuid(UUID.randomUUID()),
"You can 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 - for example, 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);
}
Verificação
Execute os testes de produtos Bluetooth aplicáveis para verificar a compatibilidade do dispositivo com o Bluetooth 5.