前言
针对附近 Wi-Fi 设备的新运行时权限:Android 13 引入了 NEARBY_WIFI_DEVICES 权限,该权限属于 NEARBY_DEVICES 权限组,适用于会管理设备与附近 Wi-Fi 接入点连接情况的应用。借助此权限,您可以更轻松地说明应用为何访问附近的 Wi-Fi 设备;在以前的 Android 版本中,这类应用需要声明 ACCESS_FINE_LOCATION 权限。
如果您的应用以 Android 13 为目标平台并调用多个不同的 Wi-Fi API,则必须从用户处获得这项新权限。
注意:如果您的应用尝试在未获得适当权限的情况下调用 Wi-Fi API,则会发生 SecurityException。
这项新权限会影响几个不同的 Wi-Fi 用例,包括以下用例:
NEARBY_WIFI_DEVICES 权限是附近的设备权限组的一部分。此权限组在 Android 12(API 级别 31)中添加,还包含与蓝牙和超宽带相关的权限。如果您的应用请求此权限组中的多项权限,用户会看到一个运行时对话框,其中会请求用户批准您的应用访问附近的设备。在系统设置中,用户必须以组的形式启用和停用附近的设备权限;例如,针对给定应用,用户无法既停用其 Wi-Fi 访问权限,但又保持启用其蓝牙使用权限。
在以 Android 13 为目标平台时,请考虑您的应用是否会通过 Wi-Fi API 推导物理位置;如果不会,则应坚定声明此情况。如需做出此声明,请在应用的清单文件中将 usesPermissionFlags 属性设为 neverForLocation,如以下代码段所示。此过程类似于您声明绝不会将蓝牙设备信息用于获取位置信息时的过程:
<manifest ...> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" /> <application ...> ... </application> </manifest>
由于 NEARBY_WIFI_DEVICES 权限仅适用于 Android 13 或更高版本,因此您应保留对 ACCESS_FINE_LOCATION 的所有声明,以便在您的应用中提供向后兼容性。不过,只要您坚定声明应用不会使用 Wi-Fi API 推导物理位置信息,就可以将此权限的最高 SDK 版本设为 32,如下以下代码段所示:
<manifest ...> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="32" /> <application ...> ... </application> </manifest>
有几个 Wi-Fi API 仍然需要 ACCESS_FINE_LOCATION 权限才能获取位置信息,就像它们在 12L 及更低版本上的一样。示例包括 WifiManager 类中的以下方法:
如果您的应用以 Android 13 或更高版本为目标平台,您必须声明 NEARBY_WIFI_DEVICES 权限才能调用以下任何 Wi-Fi API:
WifiManager
WifiAwareManager
WifiAwareSession
WifiP2pManager
WifiRttManager
图 1 显示了搭载 12L 或更低版本的设备上的 Wi-Fi 访问工作流。请注意对 ACCESS_FINE_LOCATION 权限的依赖。
图 1. 用于确定以 12L 或更低版本为目标平台的应用是否可以获取 Wi-Fi 信息的流程图。
图 2 显示了搭载 Android 13 或更高版本的设备上的 Wi-Fi 访问工作流(对于以 Android 13 或更高版本为目标平台的应用)。请注意,只要您声明应用不会根据 Wi-Fi 设备信息推导物理位置信息,就不再需要声明 ACCESS_FINE_LOCATION 权限:

图 2. 用于确定以 Android 13 或更高版本为目标平台的应用是否可以获取 Wi-Fi 信息的流程图。
