以 Android 13(API 级别 33)或更高版本为目标平台且管理 Wi-Fi 连接的应用应请求 NEARBY_WIFI_DEVICES
运行时权限。借助此权限,您可以更轻松地说明应用为何访问附近的 Wi-Fi 设备;在以前的 Android 版本中,这类应用需要声明 ACCESS_FINE_LOCATION 权限。
注意:如果您的应用尝试在未获得适当权限的情况下调用 Wi-Fi API,则会发生 SecurityException。
该权限属于“附近的设备”权限组
NEARBY_WIFI_DEVICES 权限是附近的设备权限组的一部分。此权限组在 Android 12(API 级别 31)中添加,还包含与蓝牙和超宽带相关的权限。当您请求此权限组中的任意权限组合时,系统会显示一个运行时对话框,并请求用户批准您的应用访问附近的设备。在系统设置中,用户必须以组的形式启用和停用附近的设备权限;例如,针对给定应用,用户无法既停用其 Wi-Fi 访问权限,但又保持启用其蓝牙使用权限。
坚定地声明您的应用不会推导物理位置
在以 Android 13 或更高版本为目标平台时,请考虑您的应用是否会通过 Wi-Fi API 推导位置信息;如果不会,则应坚定声明此情况。如需做出此声明,请在应用的清单文件中将 usesPermissionFlags 属性设为 neverForLocation,如以下代码段所示。此过程类似于您声明绝不会将蓝牙设备信息用于获取位置信息时的过程:
android:usesPermissionFlags="neverForLocation" /> ... 旧版本和某些 API 需要位置信息权限 即使您的应用以 Android 13 或更高版本为目标平台,也有多个 Wi-Fi API 需要 ACCESS_FINE_LOCATION 权限。示例包括 WifiManager 类中的以下方法: getScanResults() startScan() 此外,由于 NEARBY_WIFI_DEVICES 权限仅在 Android 13 及更高版本中可用,因此您应保留 ACCESS_FINE_LOCATION 的所有声明,以在应用中提供向后兼容性。不过,只要您的应用不以其他方式依赖精确位置信息,您就可以将此权限的最大 SDK 版本设置为 32,如以下代码段所示: android:maxSdkVersion="32" /> ... 检查需要相应权限的 API 如果您的应用以 Android 13 或更高版本为目标平台,您必须声明 NEARBY_WIFI_DEVICES 权限才能调用以下任何 Wi-Fi API: WifiManager startLocalOnlyHotspot() WifiAwareManager attach(AttachCallback attachCallback, IdentityChangedListener identityChangedListener, Handler handler) WifiAwareSession publish() subscribe() WifiP2pManager addLocalService() connect() createGroup() discoverPeers() discoverServices() requestDeviceInfo() requestGroupInfo() requestPeers() WifiRttManager startRanging() Wi-Fi 访问工作流 图 1 显示了搭载 Android 13 或更高版本的设备上的 Wi-Fi 访问工作流(对于以 Android 13 或更高版本为目标平台的应用)。请注意,只要您声明应用不会根据 Wi-Fi 设备信息推导物理位置信息,就不再需要声明 ACCESS_FINE_LOCATION 权限: 图 1. 用于确定以 Android 13(API 级别 33)或更高版本为目标平台的应用是否可以获取 Wi-Fi 信息的流程图。 图 2 显示了搭载 12L 或更低版本的设备上的 Wi-Fi 访问工作流。请注意对 ACCESS_FINE_LOCATION 权限的依赖。 图 2. 用于确定以 12L(API 级别 32)或更低版本为目标平台的应用是否可以获取 Wi-Fi 信息的流程图。
