Android NDK开发详解连接性之使用仅限本地的 WLAN 热点并设定访问权限
使用仅限本地的 WLAN 热点
您可以使用仅限本地使用的热点,让连接到 WLAN 热点的设备上的应用能够相互通信。通过此方法创建的网络将无法访问互联网。每个应用可以针对热点发出单个请求,但多个应用可同时请求热点。当多个应用成功同时注册时,它们会共享底层热点。当热点可供使用时,系统会调用 LocalOnlyHotspotCallback.onStarted(LocalOnlyHotspotReservation)。
如果您的应用以 Android 13(API 级别 33)或更高版本为目标平台,您必须请求 NEARBY_WIFI_DEVICES 才能使用仅限本地使用的热点,如以下代码段所示。以较低 Android 版本为目标平台的应用必须请求 ACCESS_FINE_LOCATION。
<manifest ...>
<<!-- If your app targets Android 13 (API level 33)
or higher, you must declare the NEARBY_WIFI_DEVICES permission. -->
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
<!-- If your app derives location information from
Wi-Fi APIs, don't include the "usesPermissionFlags"
attribute. -->
android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
<!-- If any feature in your app relies on
precise location information, don't include the
"maxSdkVersion" attribute. -->
android:maxSdkVersion="32" />
<application ...>
...
</application>
</manifest>
如需详细了解如何使用仅限本地使用的热点,请参阅 startLocalOnlyHotspot()。
请求对附近 Wi-Fi 设备的访问权限
以 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,如以下代码段所示。此过程类似于您声明绝不会将蓝牙设备信息用于获取位置信息时的过程:
<manifest ...>
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
android:usesPermissionFlags="neverForLocation" />
<application ...>
...
</application>
</manifest>
旧版和部分 API 需要位置信息权限
一些 Wi-Fi API 需要 ACCESS_FINE_LOCATION 权限,即使您的应用以 Android 13 或更高版本为目标平台也是如此。示例包括 WifiManager 类中的以下方法:
getScanResults()
startScan()
此外,由于 NEARBY_WIFI_DEVICES 权限仅适用于 Android 13 及更高版本,因此您应保留对 ACCESS_FINE_LOCATION 的所有声明,以在应用中提供向后兼容性。不过,只要您的应用不依赖于确切位置信息,您就可以将此权限的最高 SDK 版本设置为 32,如以下代码段所示:
<manifest ...>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="32" />
<application ...>
...
</application>
</manifest>
检查需要该权限的 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 显示了搭载 Android 12L 或更低版本的设备上的 Wi-Fi 访问工作流。请注意对 ACCESS_FINE_LOCATION 权限的依赖。
图 2. 用于确定以 12L(API 级别 32)或更低版本为目标平台的应用是否可以访问 Wi-Fi 信息的流程图。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2023-11-02。