【问题标题】:After connecting to WiFi programmatically, disconnects a few seconds later以编程方式连接到 WiFi 后,几秒钟后断开连接
【发布时间】:2018-02-12 15:25:03
【问题描述】:

我在代表用户切换 wifi 网络时遇到问题。我们有一个物联网设备,我们需要连接它才能进行设置。使用WifiManagerConnectivityManager,我可以建立连接,甚至可以对其进行REST 调用,但它会在大约10 秒后变回来。我不明白为什么。设备中有几行奇怪的日志行,我确定它们是相关的,但我不知道如何修复,主要是:

02-12 15:36:13.441 E/WifiConfigManager: UID 10356 does not have permission to update configuration "REDACTED"NONE
02-12 15:36:13.442 I/WifiStateMachine: connectToUserSelectNetwork Allowing uid 10356 with insufficient permissions to connect=90
...
02-12 15:36:13.470 E/WifiVendorHal: stopRssiMonitoring(l.2156) failed {.code = ERROR_NOT_AVAILABLE, .description = }
02-12 15:36:13.470 W/WifiConfigManager: Looking up network with invalid networkId -1
...
02-12 15:36:16.882 D/WifiStateMachine: NETWORK_STATUS_UNWANTED_VALIDATION_FAILED
...
02-12 15:36:17.041 D/WifiPermissionsUtil: Denied: no location permission

那里有很多关于权限的内容,但我想我都在要求它们:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

我要求提供位置的 RuntimePermission,因为我正在使用 SDK 27 的设备上对此进行测试。更重要的是,它确实让我可以连接,但只是在几秒钟后改变了主意。

【问题讨论】:

  • 是的,我也遇到了同样的问题,但我仍然无法弄清楚...非常烦人,我什至尝试使用bindProcessToNetwork,但它仍然给了我这些问题:(
  • 您找到解决方案了吗?

标签: android


【解决方案1】:

当您尝试使用WifiManager.startScan() 扫描网络时会导致此问题,因为 Android 已更改其权限模型。您需要检查运行时权限以访问粗略/精细位置,并且您还必须检查位置提供程序 (GPS) 是否已打开。否则,您将不会获得任何位置更新。在您的情况下,位置更新还包含您已扫描的 wifi SSID。

另外请注意,如果用户之前没有通过系统设置连接到该设备,您必须检查,因为应用不允许从应用内连接到用户定义的接入点。要允许应用代表用户再次连接,用户必须在系统设置中删除/忘记该网络。如果您不检查,您将收到来自子系统的请求者身份验证错误。

物联网 Wifi 设备的另一个注意事项:它们大多是“无头”接入点,即没有互联网。许多 Android 设备都存在问题,即它们需要有效的强制网络门户。看到这个问题:https://android.stackexchange.com/questions/130265/stay-connected-to-specific-wifi-which-has-no-internet

要解决此问题,您必须使用静态 IP 地址进行连接。但是,Android 不提供 API 以编程方式进行设置。因此,您必须使用此处所述的反射:Set static IP and gateway programmatically in Android 6.x (Marshmallow)

【讨论】:

    【解决方案2】:

    在尝试连接到现有 WiFi 配置时,我也有过类似的经历,我发现 Denis 的回答非常有帮助。以下是我在运行 Android 8.1.0 的 Nexus 5x 上的发现。

    当一切正常时:

    为了保持与无法访问互联网的 WiFi 网络的持久连接,您需要调用:

    • (a) bindToProcess() 在该网络上,告诉您的应用在没有互联网连接的情况下通过该网络路由其所有流量,或者

    • (b) 您可以将 HTTP 客户端配置为使用所需网络的套接字工厂。

    如果您使用您的应用创建的 WiFi 配置执行上述任一操作,则系统不会因为无法访问互联网而断开您与网络的连接。

    如果他们不这样做:

    如果您尝试连接的 WiFi 配置不是由您的应用创建(基于应用的 UID),您仍然可以连接,并且可以执行 (a )(b),但系统会在短时间内断开您与该网络的连接。这对我来说似乎是一个 Android 错误。系统允许您连接到您未创建的配置,但会报告以下内容:

    UID xxxxx does not have permission to update configuration
    
    connectToUserSelectNetwork Allowing uid xxxxx with insufficient permissions to connect=16
    

    不久之后,它将断开您与配置的网络的连接,就像您不执行 (a)(b) 时一样。这似乎是 Android 系统的任何部分的实现中的一个错误,因为您无法访问互联网而将您踢出网络。要么您一开始就不能连接到该网络,要么它应该允许您使用 (a)(b) 保持连接。

    当用户通过系统 WiFi 设置手动配置该网络时,或者当您在 Android Studio 中重新运行应用程序时,您的应用程序未创建 WiFi 配置。因此,如果您正在调试并配置网络,然后重新运行应用程序,您将无法保持与之前配置的网络的持久连接,因为您的 UID 将发生变化。

    解决方案

    实际的解决方案非常简单。您可以删除之前的 WiFi 配置(即使您显然没有“足够”的权限来正确连接它!)

    // Find an existing network configuration with the SSID you're trying to connect to:
    val configuration = wifiManager.configuredNetworks.firstOrNull { network -> network.SSID == "\"YOUR_SSID\"" }
    
    // Remove the configuration
    if (configuration != null) {
        wifiManager.removeNetwork(configuration.networkId)
    }
    

    现在您可以创建新配置并连接到它,然后执行 (a)(b) 并保持持久的网络连接。

    我已提交有关 Android 问题跟踪器的错误报告: https://issuetracker.google.com/issues/123896447

    【讨论】:

    • 当我按照您的建议尝试删除网络时,removeNetwork() 返回 false 并且实际上并未删除网络。
    • 由于这是一个错误,因此您遇到不同的行为也就不足为奇了。很遗憾,Google 没有提供任何建议,我们可以认为这不适用于某些设备/平台。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多