저전력 블루투스 광고

저전력 블루투스(BLE)는 대체로 절전 모드를 유지하여 전력을 절약합니다. BLE는 광고를 만들고 짧은 연결을 하기 위해서만 절전 모드를 해제하므로 광고가 전력 소비와 데이터 전송 대역폭 모두에 영향을 미칩니다.

블루투스 5 광고 확장

Android 8.0은 BLE에 브로드캐스팅 개선사항 및 유연한 데이터 광고를 제공하는 블루투스 5를 지원합니다. 블루투스 5는 블루투스 4.2의 감소한 전력 소비를 유지하고 사용자가 증가한 대역폭이나 범위를 선택할 수 있는 물리적 레이어(PHY)를 지원합니다. 자세한 내용은 블루투스 5 핵심 사양을 참고하세요.

구현

새로운 블루투스 5 기능은 호환되는 블루투스 컨트롤러가 있는 Android 8.0을 실행하는 기기에 자동으로 제공됩니다. 기기가 블루투스 5 기능을 지원하는지 확인하려면 다음 BluetoothAdapter 메서드를 사용하세요.

  • isLe2MPhySupported()
  • isLeCodedPhySupported()
  • isLeExtendedAdvertisingSupported()
  • isLePeriodicAdvertisingSupported()

광고 기능을 중지하려면 칩 공급업체와 협력하여 칩셋 지원을 중지하세요.

블루투스 PHY는 서로 배타적이며 각 PHY의 동작은 블루투스 SIG에 의해 사전 정의됩니다. 기본적으로 Android 8.0은 블루투스 4.2의 블루투스 LE 1M PHY를 사용합니다. android.bluetooth.le 패키지는 다음 API를 통해 블루투스 5 광고 기능을 노출합니다.

  • AdvertisingSet
  • AdvertisingSetCallback
  • AdvertisingSetParameters
  • PeriodicAdvertisingParameters

블루투스 광고 설정을 수정하려면 android.bluetooth.le.BluetoothLeAdvertiser startAdvertisingSet() 메서드를 사용하여 AdvertisingSet를 만드세요. 블루투스 5 또는 블루투스 5 광고 기능의 지원이 중지된 경우에도 API 기능이 LE 1M PHY에 적용될 수 있습니다.

이 앱에서는 광고에 블루투스 LE 1M PHY를 사용합니다.

  // 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);
}

이 앱에서는 광고에 BLE 2M PHY를 사용합니다. 앱은 먼저 기기가 사용 중인 기능을 지원하는지 확인합니다. 광고 기능이 지원되면 앱이 BLE 2M PHY를 기본 PHY로 구성합니다. 2M PHY가 활성화된 경우 광고가 블루투스 4.x 컨트롤러를 지원하지 않으므로 setLegacyModefalse로 설정됩니다. 이 예에서는 광고하는 동안 매개변수를 수정하고 광고도 일시중지합니다.

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 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);
}

인증

블루투스 5와의 기기 호환성을 확인하려면 관련 블루투스 제품 테스트를 실행하세요.

AOSP에는 블루투스 5용 테스트가 포함된 Android 커뮤니케이션 도구 모음(ACTS)이 포함되어 있습니다. 블루투스 5용 ACTS 테스트는 tools/test/connectivity/acts/tests/google/ble/bt5에서 찾을 수 있습니다.