蓝牙权限

要在应用中使用蓝牙功能,您必须声明多个 权限。您还应指定您的应用是否要求 支持传统蓝牙或蓝牙低功耗 (BLE)。如果您的 应用不需要标准蓝牙或 BLE,但仍然可以从这些方面获益 您可以在运行时检查可用性

声明权限

您在应用中声明的权限集取决于应用的目标 SDK 版本。

以 Android 12 或更高版本为目标平台

注意 :在 Android 8.0(API 级别 26)及更高版本中, 副屏模式 设备管理器 (CDM) 提供了一种更精简的方式连接到 (与本部分所述的权限相比)。通过 CDM 系统代表您的应用提供配对界面,且无需 位置信息权限。

如果您想要更好地控制配对和连接体验,请使用 授予本节中说明的权限

<ph type="x-smartling-placeholder">
</ph> 蓝牙权限对话框
“系统权限”对话框,要求用户执行以下操作: 授予应用权限,以发现、通告和连接到附近的设备 设备。

如果您的应用以 Android 12(API 级别 31)或更高版本为目标平台,请声明以下内容: 权限:

  1. 如果您的应用查找蓝牙 设备,例如 BLE 外围设备,声明 BLUETOOTH_SCAN 权限。
  2. 如果您的应用使当前设备可被其他蓝牙检测到 设备, 声明 BLUETOOTH_ADVERTISE 权限。
  3. 如果您的应用通过已配对的蓝牙进行通信 设备时,声明 BLUETOOTH_CONNECT 权限。
  4. 对于旧版蓝牙相关的权限声明,请将 android:maxSdkVersion 设为 30。这个应用兼容性步骤有助于系统 仅授予应用在安装时所需的蓝牙权限 搭载 Android 12 或更高版本的设备。
  5. 如果您的应用使用蓝牙扫描结果来推导物理位置,请声明 该 ACCESS_FINE_LOCATION 权限。否则,您可以坚定地断言您的应用不会派生 实际所处位置

BLUETOOTH_ADVERTISEBLUETOOTH_CONNECTBLUETOOTH_SCAN 权限是运行时权限。因此,您必须明确地请求用户 审批,然后才能查找 使用蓝牙设备、将某个设备设置为可被其他设备检测到,或 以及已配对的蓝牙设备时当您的应用请求至少一个 这些权限后,系统会提示用户允许您的应用访问 附近的设备,如图 1 所示。

以下代码段演示了如何声明与蓝牙相关的 权限(如果应用以 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>

坚定地声明您的应用不会推导物理位置

如果您的应用不使用蓝牙扫描结果来推导物理位置,则 可以明确断言您的应用绝不会使用蓝牙权限 推导物理位置。为此,请完成以下步骤:

  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 是必填项 可执行任何传统蓝牙或 BLE 通信,例如请求 连接、接受连接以及传输数据的操作。
  • ACCESS_FINE_LOCATION 因为在 Android 11 及更低版本中,蓝牙扫描 可能被用来收集 用户。

由于位置权限属于运行时权限, 您必须在运行时请求这些权限 以及如何在清单中声明它们

发现本地蓝牙设备

如果您希望应用启动设备发现或操纵蓝牙 您必须声明 BLUETOOTH_ADMIN 权限。大多数应用需要此权限仅仅是为了发现 本地蓝牙设备请勿使用此角色授予的其他能力 权限,除非应用是“超级管理员”修改蓝牙设置 。在应用清单文件中声明权限。例如:

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

如果您的应用支持某项服务,并且可以在 Android 10(API 级别 29)或 Android 11,您还必须声明 ACCESS_BACKGROUND_LOCATION 发现蓝牙设备的权限。如需详细了解 相关要求,请参阅在 背景

以下代码段展示了如何声明 ACCESS_BACKGROUND_LOCATION 权限:

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

请参阅 <uses-permission> 参考,详细了解如何声明应用权限。

指定蓝牙功能使用情况

如果蓝牙是应用的关键部分,您可以向清单添加标志 文件来指明此要求。通过 <uses-feature> 元素允许 您可以指定应用使用的硬件类型 必填字段。

此示例展示了如何指明您的蓝牙 应用。

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

如果您的应用依赖于低功耗蓝牙,您可以:

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

如果您认为此功能是应用的必备功能,那么 Google Play 商店会 向缺少这些功能的设备的用户隐藏您的应用。因此, 只有在应用无法运行时才能将必需属性设为 true 功能

在运行时检查功能可用性

使您的应用程序可供不支持标准蓝牙或 使用 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);