Разрешения Bluetooth

Чтобы использовать функции Bluetooth в приложении, необходимо запросить несколько разрешений. Также необходимо указать, требуется ли вашему приложению поддержка Bluetooth Classic или Bluetooth с низким энергопотреблением (BLE). Если ваше приложение не требует наушников Bluetooth или BLE, но может использовать эти технологии, вы можете проверить их доступность во время выполнения.

Объявление разрешений

Набор разрешений, которые вы объявляете в приложении, зависит от целевой версии SDK.

Целевая версия Android 12 или более поздняя

Примечание. В Android 8.0 (уровень API 26) и более поздних версиях Менеджер подключенных устройств предлагает более простой способ подключения к сопутствующим устройствам, чем разрешения, описанные в этом разделе. Система CDM предоставляет интерфейс для подключения от имени вашего приложения и не требует разрешений на доступ к данным о местоположении.

Если вы хотите лучше контролировать процесс подключения и установки связи, используйте разрешения, описанные в этом разделе.

Диалоговое окно разрешений Bluetooth
Диалоговое окно системных разрешений, в котором пользователю предлагается предоставить приложению разрешение на обнаружение устройств поблизости, рекламу и подключение к ним.

Если ваше приложение предназначено для Android 12 (уровень API 31) или более поздней версии, объявите в файле манифеста следующие разрешения:

  1. Если ваше приложение ищет устройства Bluetooth, например периферийные устройства BLE, объявите разрешение BLUETOOTH_SCAN.
  2. Если ваше приложение делает текущее устройство видимым для других устройств Bluetooth, объявите разрешение BLUETOOTH_ADVERTISE.
  3. Если приложение обменивается данными с уже подключенными устройствами Bluetooth, объявите разрешение BLUETOOTH_CONNECT.
  4. Для деклараций разрешений, связанных с Bluetooth, установите значение android:maxSdkVersion, равное 30. Этот шаг совместимости приложений помогает системе предоставлять вашему приложению только те разрешения Bluetooth, которые ему нужны при установке на устройствах с Android 12 или более поздней версии.
  5. Если ваше приложение использует результаты поиска Bluetooth-устройств для определения физического местоположения, объявите разрешение ACCESS_FINE_LOCATION. В противном случае вы можете заявить, что ваше приложение не определяет физическое местоположение, и установить для разрешения ACCESS_FINE_LOCATION значение android:maxSdkVersion, равное 30.

Разрешения BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT и BLUETOOTH_SCAN являются динамическими разрешениями. Поэтому, прежде чем искать устройства Bluetooth, делать устройство видимым для других устройств или обмениваться данными с уже подключенными устройствами Bluetooth, необходимо явным образом запросить разрешение пользователя в приложении. Когда приложение запрашивает хотя бы одно из этих разрешений, система предлагает пользователю разрешить приложению доступ к устройствам поблизости, как показано на рисунке 1.

В следующем фрагменте кода показано, как объявить разрешения, связанные с Bluetooth, в приложении, предназначенном для Android 12 или более поздней версии:

<manifest>
    <!-- Request legacy Bluetooth permissions on older devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH"
                     android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
                     android:maxSdkVersion="30" />

    <!-- Needed only if your app looks for Bluetooth devices.
         If your app doesn't use Bluetooth scan results to derive physical
         location information, you can
         <a href="#assert-never-for-location">strongly assert that your app
         doesn't derive physical location</a>. -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

    <!-- Needed only if your app makes the device discoverable to Bluetooth
         devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />

    <!-- Needed only if your app communicates with already-paired Bluetooth
         devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

    <!-- Needed only if your app uses Bluetooth scan results to derive
         physical location. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    ...
</manifest>

Убедительно докажите, что ваше приложение не определяет физическое местоположение.

Если ваше приложение не использует результаты поиска Bluetooth-устройств для определения физического местоположения, вы можете заявить, что оно никогда не использует разрешения Bluetooth для определения физического местоположения. Для этого выполните следующие действия:

  1. Добавьте атрибут android:usesPermissionFlags в декларацию разрешений BLUETOOTH_SCAN и задайте для него значение neverForLocation.

  2. Если вашему приложению не требуются данные о местоположении, удалите разрешение ACCESS_FINE_LOCATION из манифеста приложения.

В следующем фрагменте кода показано, как обновить файл манифеста приложения:

<manifest>
    <!-- Include "neverForLocation" only if you can strongly assert that
         your app never derives physical location from Bluetooth scan results. -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
                     android:usesPermissionFlags="neverForLocation" />

    <!-- Set maxSdkVersion to 30 if you can strongly assert that, on
         Android 12 and higher, your app never derives physical location from
         Bluetooth scan results and doesn't need location access for any other
         purpose. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
                     android:maxSdkVersion="30" />
    ...
</manifest>

Целевая версия Android 11 или более ранняя

Если ваше приложение предназначено для Android 11 (уровень API 30) или более ранней версии, объявите в файле манифеста следующие разрешения:

  • Разрешение BLUETOOTH необходимо для выполнения любых действий, связанных с наушниками Bluetooth или BLE, например для запроса или принятия подключения и передачи данных.
  • ACCESS_FINE_LOCATION необходимо, поскольку в Android 11 и более ранних версиях поиск Bluetooth-устройств может использоваться для сбора информации о местоположении пользователя.

Поскольку разрешения на доступ к данным о местоположении являются динамическими разрешениями, вы должны запрашивать их во время выполнения, а также объявлять в манифесте.

Обнаружение локальных устройств Bluetooth

Если вы хотите, чтобы приложение инициировало обнаружение устройств или управляло настройками Bluetooth, необходимо объявить разрешение BLUETOOTH_ADMIN. Большинству приложений это разрешение нужно только для обнаружения устройств Bluetooth поблизости. Не используйте другие возможности, предоставляемые этим разрешением, если только приложение не является "менеджером питания", который изменяет настройки Bluetooth по запросу пользователя. Объявите разрешение в файле манифеста приложения. Пример:

<manifest>
...
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
...
</manifest>

Если ваше приложение поддерживает сервис и может работать на Android 10 (уровень API 29) или Android 11, вы также должны объявить разрешение ACCESS_BACKGROUND_LOCATION для обнаружения устройств Bluetooth. Подробнее о получении доступа к данным о местоположении в фоновом режиме…

В следующем фрагменте кода показано, как объявить разрешение ACCESS_BACKGROUND_LOCATION:

<manifest>
...
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
...
</manifest>

Дополнительную информацию о том, как объявлять разрешения для приложений, можно найти в справочнике по <uses-permission>.

Укажите, как используется Bluetooth

Если Bluetooth – критически важная часть вашего приложения, вы можете добавить в файл манифеста флаги, указывающие на это требование. Элемент <uses-feature> позволяет указать тип аппаратного обеспечения, которое использует ваше приложение, и необходимость его наличия.

В примере ниже показано, как указать, что для работы приложения требуется Bluetooth Classic.

<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>

Если ваше приложение использует Bluetooth с низким энергопотреблением, вы можете использовать следующее:

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

Если вы укажете, что функция необходима для работы приложения, то Google Play будет скрывать его от пользователей устройств, на которых эта функция не поддерживается. Поэтому задавайте для атрибута required значение true, только если приложение не может работать без этой функции.

Проверка доступности функций во время выполнения

Чтобы приложение было доступно на устройствах, которые не поддерживают наушники Bluetooth или BLE, добавьте в манифест элемент <uses-feature>, но задайте для него значение required="false". Затем во время выполнения вы можете определить доступность функции с помощью PackageManager.hasSystemFeature():

Kotlin

// Check to see if the Bluetooth classic feature is available.
val bluetoothAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)

// Check to see if the BLE feature is available.
val bluetoothLEAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)

Java

// Use this check to determine whether Bluetooth classic is supported on the device.
// Then you can selectively disable BLE-related features.
boolean bluetoothAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);

// Use this check to determine whether BLE is supported on the device. Then
// you can selectively disable BLE-related features.
boolean bluetoothLEAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);