Разрешения Bluetooth

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

Объявить разрешения

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

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

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

Разрешения 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" />

    <!-- Not needed if you can strongly assert that your app never derives
         physical location from Bluetooth scan results and doesn't need location
         access for any other purpose. -->
    <strike><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /></strike>
    ...
</manifest>

Таргетинг на Android 11 или более раннюю версию

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

  • BLUETOOTH необходим для выполнения любого соединения Bluetooth Classic или 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 Low Energy, вы можете использовать следующее:

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

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

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

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

Котлин

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

Ява

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

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

Объявить разрешения

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

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

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

Разрешения 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" />

    <!-- Not needed if you can strongly assert that your app never derives
         physical location from Bluetooth scan results and doesn't need location
         access for any other purpose. -->
    <strike><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /></strike>
    ...
</manifest>

Таргетинг на Android 11 или более раннюю версию

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

  • BLUETOOTH необходим для выполнения любого соединения Bluetooth Classic или 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 Low Energy, вы можете использовать следующее:

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

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

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

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

Котлин

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

Ява

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