声明权限

声明权限

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

声明权限

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

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

注意:在 Android 8.0(API 级别 26)及更高版本上,与本部分介绍的权限相比,配套设备管理器 (CDM) 提供了一种更便捷的连接到配套设备的方法。CDM 系统代表您的应用提供配对 UI,且无需位置信息权限。

如果您想更好地控制配对和连接体验,请使用本部分所述的权限。

系统权限对话框,询问用户是否授予应用权限以发现、广播和连接到附近的设备。

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

如果您的应用查找蓝牙设备,例如 BLE 外设,请声明BLUETOOTH_SCAN 权限。

如果您的应用使当前设备可被其他蓝牙设备发现,请声明BLUETOOTH_ADVERTISE 权限。

如果您的应用与已配对的蓝牙设备通信,请声明BLUETOOTH_CONNECT 权限。

对于您声明的旧版蓝牙相关权限,将 android:maxSdkVersion 设置为 30。此应用兼容性步骤有助于系统在设备运行 Android 12 或更高版本时,仅授予应用所需的蓝牙权限。

如果您的应用使用蓝牙扫描结果来推断物理位置,请声明ACCESS_FINE_LOCATION 权限。否则,您可以明确声明您的应用不会推断物理位置,并将 ACCESS_FINE_LOCATION 权限的 android:maxSdkVersion 设置为 30。

BLUETOOTH_ADVERTISE、BLUETOOTH_CONNECT 和 BLUETOOTH_SCAN 权限是运行时权限。因此,在您查找蓝牙设备、使设备可被其他设备发现或与已配对的蓝牙设备通信之前,您必须在应用中明确请求用户批准。当您的应用请求这些权限中的至少一个时,系统会提示用户允许您的应用访问附近的设备,如图 1 所示。

以下代码片段展示了如果您的应用目标平台为 Android 12 或更高版本,如何在应用中声明蓝牙相关权限:

android:maxSdkVersion="30" />

android:maxSdkVersion="30" />

...

明确声明您的应用不会推断物理位置

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

将 android:usesPermissionFlags 属性添加到您的 BLUETOOTH_SCAN 权限声明中,并将此属性的值设置为 neverForLocation。

注意:如果您在 android:usesPermissionFlags 中包含 neverForLocation,一些 BLE 信标将从扫描结果中被过滤掉。

如果您的应用不需要位置信息,请从应用的清单文件中移除 ACCESS_FINE_LOCATION 权限。

以下代码片段展示了如何更新应用的清单文件:

android:usesPermissionFlags="neverForLocation" />

android:maxSdkVersion="30" />

...

目标平台为 Android 11 或更低版本

如果您的应用目标平台为 Android 11(API 级别 30)或更低版本,请在应用的清单文件中声明以下权限:

BLUETOOTH 是执行任何传统蓝牙或 BLE 通信所必需的,例如请求连接、接受连接和传输数据。

ACCESS_FINE_LOCATION 是必需的,因为在 Android 11 及更低版本上,蓝牙扫描可能会用于收集用户的地理位置信息。

注意:在运行 Android 8.0 或更高版本的设备上,您可以使用 CompanionDeviceManager 代表您的应用执行对附近配套设备的扫描,而无需位置信息权限。有关此选项的更多信息,请参阅配套设备配对。

由于位置权限是运行时权限,您除了在清单中声明这些权限外,还必须在运行时请求这些权限。

发现本地蓝牙设备

如果您希望您的应用启动设备发现或操纵蓝牙设置,您必须声明 BLUETOOTH_ADMIN 权限。大多数应用仅需此权限即可发现本地蓝牙设备。除非应用是根据用户请求修改蓝牙设置的“电源管理器”应用,否则请勿使用此权限授予的其他功能。在您的应用清单文件中声明此权限。例如:

...

...

如果您的应用支持服务并可在 Android 10(API 级别 29)或 Android 11 上运行,您还必须声明 ACCESS_BACKGROUND_LOCATION 权限才能发现蓝牙设备。有关此要求的更多信息,请参阅在后台访问位置信息。

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

...

...

有关声明应用权限的更多信息,请参阅 参考。

指定蓝牙功能使用情况

如果蓝牙是您的应用的关键组成部分,您可以在清单文件中添加标志来指示此要求。 元素允许您指定应用使用的硬件类型以及是否必需。

此示例展示了如何指示您的应用需要传统蓝牙。

如果您的应用依赖低功耗蓝牙,您可以使用以下代码:

如果您将此功能设置为必需,Google Play 商店将对设备不具备这些功能的用户隐藏您的应用。因此,只有在您的应用无法在没有此功能的情况下工作时,才应将 required 属性设置为 true。

在运行时检查功能可用性

为了使您的应用可在不支持传统蓝牙或 BLE 的设备上使用,您仍应在应用的清单中包含 元素,但将 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);

相关推荐